diff options
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 6a3a5fa1526d..6c683b37f2ce 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -91,6 +91,7 @@ struct futex_pi_state { | |||
91 | 91 | ||
92 | /** | 92 | /** |
93 | * struct futex_q - The hashed futex queue entry, one per waiting task | 93 | * struct futex_q - The hashed futex queue entry, one per waiting task |
94 | * @list: priority-sorted list of tasks waiting on this futex | ||
94 | * @task: the task waiting on the futex | 95 | * @task: the task waiting on the futex |
95 | * @lock_ptr: the hash bucket lock | 96 | * @lock_ptr: the hash bucket lock |
96 | * @key: the key the futex is hashed on | 97 | * @key: the key the futex is hashed on |
@@ -104,7 +105,7 @@ struct futex_pi_state { | |||
104 | * | 105 | * |
105 | * A futex_q has a woken state, just like tasks have TASK_RUNNING. | 106 | * A futex_q has a woken state, just like tasks have TASK_RUNNING. |
106 | * It is considered woken when plist_node_empty(&q->list) || q->lock_ptr == 0. | 107 | * It is considered woken when plist_node_empty(&q->list) || q->lock_ptr == 0. |
107 | * The order of wakup is always to make the first condition true, then | 108 | * The order of wakeup is always to make the first condition true, then |
108 | * the second. | 109 | * the second. |
109 | * | 110 | * |
110 | * PI futexes are typically woken before they are removed from the hash list via | 111 | * PI futexes are typically woken before they are removed from the hash list via |
@@ -168,7 +169,7 @@ static void get_futex_key_refs(union futex_key *key) | |||
168 | 169 | ||
169 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { | 170 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { |
170 | case FUT_OFF_INODE: | 171 | case FUT_OFF_INODE: |
171 | atomic_inc(&key->shared.inode->i_count); | 172 | ihold(key->shared.inode); |
172 | break; | 173 | break; |
173 | case FUT_OFF_MMSHARED: | 174 | case FUT_OFF_MMSHARED: |
174 | atomic_inc(&key->private.mm->mm_count); | 175 | atomic_inc(&key->private.mm->mm_count); |
@@ -295,7 +296,7 @@ void put_futex_key(int fshared, union futex_key *key) | |||
295 | * Slow path to fixup the fault we just took in the atomic write | 296 | * Slow path to fixup the fault we just took in the atomic write |
296 | * access to @uaddr. | 297 | * access to @uaddr. |
297 | * | 298 | * |
298 | * We have no generic implementation of a non destructive write to the | 299 | * We have no generic implementation of a non-destructive write to the |
299 | * user address. We know that we faulted in the atomic pagefault | 300 | * user address. We know that we faulted in the atomic pagefault |
300 | * disabled section so we can as well avoid the #PF overhead by | 301 | * disabled section so we can as well avoid the #PF overhead by |
301 | * calling get_user_pages() right away. | 302 | * calling get_user_pages() right away. |
@@ -515,7 +516,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, | |||
515 | */ | 516 | */ |
516 | pi_state = this->pi_state; | 517 | pi_state = this->pi_state; |
517 | /* | 518 | /* |
518 | * Userspace might have messed up non PI and PI futexes | 519 | * Userspace might have messed up non-PI and PI futexes |
519 | */ | 520 | */ |
520 | if (unlikely(!pi_state)) | 521 | if (unlikely(!pi_state)) |
521 | return -EINVAL; | 522 | return -EINVAL; |
@@ -736,8 +737,8 @@ static void wake_futex(struct futex_q *q) | |||
736 | 737 | ||
737 | /* | 738 | /* |
738 | * We set q->lock_ptr = NULL _before_ we wake up the task. If | 739 | * We set q->lock_ptr = NULL _before_ we wake up the task. If |
739 | * a non futex wake up happens on another CPU then the task | 740 | * a non-futex wake up happens on another CPU then the task |
740 | * might exit and p would dereference a non existing task | 741 | * might exit and p would dereference a non-existing task |
741 | * struct. Prevent this by holding a reference on p across the | 742 | * struct. Prevent this by holding a reference on p across the |
742 | * wake up. | 743 | * wake up. |
743 | */ | 744 | */ |
@@ -1131,11 +1132,13 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex, | |||
1131 | 1132 | ||
1132 | /** | 1133 | /** |
1133 | * futex_requeue() - Requeue waiters from uaddr1 to uaddr2 | 1134 | * futex_requeue() - Requeue waiters from uaddr1 to uaddr2 |
1134 | * uaddr1: source futex user address | 1135 | * @uaddr1: source futex user address |
1135 | * uaddr2: target futex user address | 1136 | * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED |
1136 | * nr_wake: number of waiters to wake (must be 1 for requeue_pi) | 1137 | * @uaddr2: target futex user address |
1137 | * nr_requeue: number of waiters to requeue (0-INT_MAX) | 1138 | * @nr_wake: number of waiters to wake (must be 1 for requeue_pi) |
1138 | * requeue_pi: if we are attempting to requeue from a non-pi futex to a | 1139 | * @nr_requeue: number of waiters to requeue (0-INT_MAX) |
1140 | * @cmpval: @uaddr1 expected value (or %NULL) | ||
1141 | * @requeue_pi: if we are attempting to requeue from a non-pi futex to a | ||
1139 | * pi futex (pi to pi requeue is not supported) | 1142 | * pi futex (pi to pi requeue is not supported) |
1140 | * | 1143 | * |
1141 | * Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire | 1144 | * Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire |
@@ -1360,10 +1363,10 @@ out: | |||
1360 | 1363 | ||
1361 | /* The key must be already stored in q->key. */ | 1364 | /* The key must be already stored in q->key. */ |
1362 | static inline struct futex_hash_bucket *queue_lock(struct futex_q *q) | 1365 | static inline struct futex_hash_bucket *queue_lock(struct futex_q *q) |
1366 | __acquires(&hb->lock) | ||
1363 | { | 1367 | { |
1364 | struct futex_hash_bucket *hb; | 1368 | struct futex_hash_bucket *hb; |
1365 | 1369 | ||
1366 | get_futex_key_refs(&q->key); | ||
1367 | hb = hash_futex(&q->key); | 1370 | hb = hash_futex(&q->key); |
1368 | q->lock_ptr = &hb->lock; | 1371 | q->lock_ptr = &hb->lock; |
1369 | 1372 | ||
@@ -1373,9 +1376,9 @@ static inline struct futex_hash_bucket *queue_lock(struct futex_q *q) | |||
1373 | 1376 | ||
1374 | static inline void | 1377 | static inline void |
1375 | queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb) | 1378 | queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb) |
1379 | __releases(&hb->lock) | ||
1376 | { | 1380 | { |
1377 | spin_unlock(&hb->lock); | 1381 | spin_unlock(&hb->lock); |
1378 | drop_futex_key_refs(&q->key); | ||
1379 | } | 1382 | } |
1380 | 1383 | ||
1381 | /** | 1384 | /** |
@@ -1391,6 +1394,7 @@ queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb) | |||
1391 | * an example). | 1394 | * an example). |
1392 | */ | 1395 | */ |
1393 | static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) | 1396 | static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) |
1397 | __releases(&hb->lock) | ||
1394 | { | 1398 | { |
1395 | int prio; | 1399 | int prio; |
1396 | 1400 | ||
@@ -1471,6 +1475,7 @@ retry: | |||
1471 | * and dropped here. | 1475 | * and dropped here. |
1472 | */ | 1476 | */ |
1473 | static void unqueue_me_pi(struct futex_q *q) | 1477 | static void unqueue_me_pi(struct futex_q *q) |
1478 | __releases(q->lock_ptr) | ||
1474 | { | 1479 | { |
1475 | WARN_ON(plist_node_empty(&q->list)); | 1480 | WARN_ON(plist_node_empty(&q->list)); |
1476 | plist_del(&q->list, &q->list.plist); | 1481 | plist_del(&q->list, &q->list.plist); |
@@ -1480,8 +1485,6 @@ static void unqueue_me_pi(struct futex_q *q) | |||
1480 | q->pi_state = NULL; | 1485 | q->pi_state = NULL; |
1481 | 1486 | ||
1482 | spin_unlock(q->lock_ptr); | 1487 | spin_unlock(q->lock_ptr); |
1483 | |||
1484 | drop_futex_key_refs(&q->key); | ||
1485 | } | 1488 | } |
1486 | 1489 | ||
1487 | /* | 1490 | /* |
@@ -1812,7 +1815,10 @@ static int futex_wait(u32 __user *uaddr, int fshared, | |||
1812 | } | 1815 | } |
1813 | 1816 | ||
1814 | retry: | 1817 | retry: |
1815 | /* Prepare to wait on uaddr. */ | 1818 | /* |
1819 | * Prepare to wait on uaddr. On success, holds hb lock and increments | ||
1820 | * q.key refs. | ||
1821 | */ | ||
1816 | ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); | 1822 | ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); |
1817 | if (ret) | 1823 | if (ret) |
1818 | goto out; | 1824 | goto out; |
@@ -1822,28 +1828,27 @@ retry: | |||
1822 | 1828 | ||
1823 | /* If we were woken (and unqueued), we succeeded, whatever. */ | 1829 | /* If we were woken (and unqueued), we succeeded, whatever. */ |
1824 | ret = 0; | 1830 | ret = 0; |
1831 | /* unqueue_me() drops q.key ref */ | ||
1825 | if (!unqueue_me(&q)) | 1832 | if (!unqueue_me(&q)) |
1826 | goto out_put_key; | 1833 | goto out; |
1827 | ret = -ETIMEDOUT; | 1834 | ret = -ETIMEDOUT; |
1828 | if (to && !to->task) | 1835 | if (to && !to->task) |
1829 | goto out_put_key; | 1836 | goto out; |
1830 | 1837 | ||
1831 | /* | 1838 | /* |
1832 | * We expect signal_pending(current), but we might be the | 1839 | * We expect signal_pending(current), but we might be the |
1833 | * victim of a spurious wakeup as well. | 1840 | * victim of a spurious wakeup as well. |
1834 | */ | 1841 | */ |
1835 | if (!signal_pending(current)) { | 1842 | if (!signal_pending(current)) |
1836 | put_futex_key(fshared, &q.key); | ||
1837 | goto retry; | 1843 | goto retry; |
1838 | } | ||
1839 | 1844 | ||
1840 | ret = -ERESTARTSYS; | 1845 | ret = -ERESTARTSYS; |
1841 | if (!abs_time) | 1846 | if (!abs_time) |
1842 | goto out_put_key; | 1847 | goto out; |
1843 | 1848 | ||
1844 | restart = ¤t_thread_info()->restart_block; | 1849 | restart = ¤t_thread_info()->restart_block; |
1845 | restart->fn = futex_wait_restart; | 1850 | restart->fn = futex_wait_restart; |
1846 | restart->futex.uaddr = (u32 *)uaddr; | 1851 | restart->futex.uaddr = uaddr; |
1847 | restart->futex.val = val; | 1852 | restart->futex.val = val; |
1848 | restart->futex.time = abs_time->tv64; | 1853 | restart->futex.time = abs_time->tv64; |
1849 | restart->futex.bitset = bitset; | 1854 | restart->futex.bitset = bitset; |
@@ -1856,8 +1861,6 @@ retry: | |||
1856 | 1861 | ||
1857 | ret = -ERESTART_RESTARTBLOCK; | 1862 | ret = -ERESTART_RESTARTBLOCK; |
1858 | 1863 | ||
1859 | out_put_key: | ||
1860 | put_futex_key(fshared, &q.key); | ||
1861 | out: | 1864 | out: |
1862 | if (to) { | 1865 | if (to) { |
1863 | hrtimer_cancel(&to->timer); | 1866 | hrtimer_cancel(&to->timer); |
@@ -1869,7 +1872,7 @@ out: | |||
1869 | 1872 | ||
1870 | static long futex_wait_restart(struct restart_block *restart) | 1873 | static long futex_wait_restart(struct restart_block *restart) |
1871 | { | 1874 | { |
1872 | u32 __user *uaddr = (u32 __user *)restart->futex.uaddr; | 1875 | u32 __user *uaddr = restart->futex.uaddr; |
1873 | int fshared = 0; | 1876 | int fshared = 0; |
1874 | ktime_t t, *tp = NULL; | 1877 | ktime_t t, *tp = NULL; |
1875 | 1878 | ||
@@ -2236,7 +2239,10 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, | |||
2236 | q.rt_waiter = &rt_waiter; | 2239 | q.rt_waiter = &rt_waiter; |
2237 | q.requeue_pi_key = &key2; | 2240 | q.requeue_pi_key = &key2; |
2238 | 2241 | ||
2239 | /* Prepare to wait on uaddr. */ | 2242 | /* |
2243 | * Prepare to wait on uaddr. On success, increments q.key (key1) ref | ||
2244 | * count. | ||
2245 | */ | ||
2240 | ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); | 2246 | ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); |
2241 | if (ret) | 2247 | if (ret) |
2242 | goto out_key2; | 2248 | goto out_key2; |
@@ -2254,7 +2260,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, int fshared, | |||
2254 | * In order for us to be here, we know our q.key == key2, and since | 2260 | * In order for us to be here, we know our q.key == key2, and since |
2255 | * we took the hb->lock above, we also know that futex_requeue() has | 2261 | * we took the hb->lock above, we also know that futex_requeue() has |
2256 | * completed and we no longer have to concern ourselves with a wakeup | 2262 | * completed and we no longer have to concern ourselves with a wakeup |
2257 | * race with the atomic proxy lock acquition by the requeue code. | 2263 | * race with the atomic proxy lock acquisition by the requeue code. The |
2264 | * futex_requeue dropped our key1 reference and incremented our key2 | ||
2265 | * reference count. | ||
2258 | */ | 2266 | */ |
2259 | 2267 | ||
2260 | /* Check if the requeue code acquired the second futex for us. */ | 2268 | /* Check if the requeue code acquired the second futex for us. */ |
@@ -2458,7 +2466,7 @@ retry: | |||
2458 | */ | 2466 | */ |
2459 | static inline int fetch_robust_entry(struct robust_list __user **entry, | 2467 | static inline int fetch_robust_entry(struct robust_list __user **entry, |
2460 | struct robust_list __user * __user *head, | 2468 | struct robust_list __user * __user *head, |
2461 | int *pi) | 2469 | unsigned int *pi) |
2462 | { | 2470 | { |
2463 | unsigned long uentry; | 2471 | unsigned long uentry; |
2464 | 2472 | ||
@@ -2647,7 +2655,7 @@ static int __init futex_init(void) | |||
2647 | * of the complex code paths. Also we want to prevent | 2655 | * of the complex code paths. Also we want to prevent |
2648 | * registration of robust lists in that case. NULL is | 2656 | * registration of robust lists in that case. NULL is |
2649 | * guaranteed to fault and we get -EFAULT on functional | 2657 | * guaranteed to fault and we get -EFAULT on functional |
2650 | * implementation, the non functional ones will return | 2658 | * implementation, the non-functional ones will return |
2651 | * -ENOSYS. | 2659 | * -ENOSYS. |
2652 | */ | 2660 | */ |
2653 | curval = cmpxchg_futex_value_locked(NULL, 0, 0); | 2661 | curval = cmpxchg_futex_value_locked(NULL, 0, 0); |