Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
futex: Fix errors in nested key ref-counting

+16 -15
+16 -15
kernel/futex.c
··· 1363 1363 { 1364 1364 struct futex_hash_bucket *hb; 1365 1365 1366 - get_futex_key_refs(&q->key); 1367 1366 hb = hash_futex(&q->key); 1368 1367 q->lock_ptr = &hb->lock; 1369 1368 ··· 1374 1375 queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb) 1375 1376 { 1376 1377 spin_unlock(&hb->lock); 1377 - drop_futex_key_refs(&q->key); 1378 1378 } 1379 1379 1380 1380 /** ··· 1478 1480 q->pi_state = NULL; 1479 1481 1480 1482 spin_unlock(q->lock_ptr); 1481 - 1482 - drop_futex_key_refs(&q->key); 1483 1483 } 1484 1484 1485 1485 /* ··· 1808 1812 } 1809 1813 1810 1814 retry: 1811 - /* Prepare to wait on uaddr. */ 1815 + /* 1816 + * Prepare to wait on uaddr. On success, holds hb lock and increments 1817 + * q.key refs. 1818 + */ 1812 1819 ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); 1813 1820 if (ret) 1814 1821 goto out; ··· 1821 1822 1822 1823 /* If we were woken (and unqueued), we succeeded, whatever. */ 1823 1824 ret = 0; 1825 + /* unqueue_me() drops q.key ref */ 1824 1826 if (!unqueue_me(&q)) 1825 - goto out_put_key; 1827 + goto out; 1826 1828 ret = -ETIMEDOUT; 1827 1829 if (to && !to->task) 1828 - goto out_put_key; 1830 + goto out; 1829 1831 1830 1832 /* 1831 1833 * We expect signal_pending(current), but we might be the 1832 1834 * victim of a spurious wakeup as well. 1833 1835 */ 1834 - if (!signal_pending(current)) { 1835 - put_futex_key(fshared, &q.key); 1836 + if (!signal_pending(current)) 1836 1837 goto retry; 1837 - } 1838 1838 1839 1839 ret = -ERESTARTSYS; 1840 1840 if (!abs_time) 1841 - goto out_put_key; 1841 + goto out; 1842 1842 1843 1843 restart = &current_thread_info()->restart_block; 1844 1844 restart->fn = futex_wait_restart; ··· 1854 1856 1855 1857 ret = -ERESTART_RESTARTBLOCK; 1856 1858 1857 - out_put_key: 1858 - put_futex_key(fshared, &q.key); 1859 1859 out: 1860 1860 if (to) { 1861 1861 hrtimer_cancel(&to->timer); ··· 2232 2236 q.rt_waiter = &rt_waiter; 2233 2237 q.requeue_pi_key = &key2; 2234 2238 2235 - /* Prepare to wait on uaddr. */ 2239 + /* 2240 + * Prepare to wait on uaddr. On success, increments q.key (key1) ref 2241 + * count. 2242 + */ 2236 2243 ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); 2237 2244 if (ret) 2238 2245 goto out_key2; ··· 2253 2254 * In order for us to be here, we know our q.key == key2, and since 2254 2255 * we took the hb->lock above, we also know that futex_requeue() has 2255 2256 * completed and we no longer have to concern ourselves with a wakeup 2256 - * race with the atomic proxy lock acquition by the requeue code. 2257 + * race with the atomic proxy lock acquisition by the requeue code. The 2258 + * futex_requeue dropped our key1 reference and incremented our key2 2259 + * reference count. 2257 2260 */ 2258 2261 2259 2262 /* Check if the requeue code acquired the second futex for us. */