diff options
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index ba0d3b83c091..99f8acce08bf 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -92,11 +92,12 @@ struct futex_pi_state { | |||
92 | * A futex_q has a woken state, just like tasks have TASK_RUNNING. | 92 | * A futex_q has a woken state, just like tasks have TASK_RUNNING. |
93 | * It is considered woken when plist_node_empty(&q->list) || q->lock_ptr == 0. | 93 | * It is considered woken when plist_node_empty(&q->list) || q->lock_ptr == 0. |
94 | * The order of wakup is always to make the first condition true, then | 94 | * The order of wakup is always to make the first condition true, then |
95 | * wake up q->waiters, then make the second condition true. | 95 | * wake up q->waiter, then make the second condition true. |
96 | */ | 96 | */ |
97 | struct futex_q { | 97 | struct futex_q { |
98 | struct plist_node list; | 98 | struct plist_node list; |
99 | wait_queue_head_t waiters; | 99 | /* There can only be a single waiter */ |
100 | wait_queue_head_t waiter; | ||
100 | 101 | ||
101 | /* Which hash list lock to use: */ | 102 | /* Which hash list lock to use: */ |
102 | spinlock_t *lock_ptr; | 103 | spinlock_t *lock_ptr; |
@@ -573,7 +574,7 @@ static void wake_futex(struct futex_q *q) | |||
573 | * The lock in wake_up_all() is a crucial memory barrier after the | 574 | * The lock in wake_up_all() is a crucial memory barrier after the |
574 | * plist_del() and also before assigning to q->lock_ptr. | 575 | * plist_del() and also before assigning to q->lock_ptr. |
575 | */ | 576 | */ |
576 | wake_up_all(&q->waiters); | 577 | wake_up(&q->waiter); |
577 | /* | 578 | /* |
578 | * The waiting task can free the futex_q as soon as this is written, | 579 | * The waiting task can free the futex_q as soon as this is written, |
579 | * without taking any locks. This must come last. | 580 | * without taking any locks. This must come last. |
@@ -930,7 +931,7 @@ static inline struct futex_hash_bucket *queue_lock(struct futex_q *q) | |||
930 | { | 931 | { |
931 | struct futex_hash_bucket *hb; | 932 | struct futex_hash_bucket *hb; |
932 | 933 | ||
933 | init_waitqueue_head(&q->waiters); | 934 | init_waitqueue_head(&q->waiter); |
934 | 935 | ||
935 | get_futex_key_refs(&q->key); | 936 | get_futex_key_refs(&q->key); |
936 | hb = hash_futex(&q->key); | 937 | hb = hash_futex(&q->key); |
@@ -1221,7 +1222,7 @@ static int futex_wait(u32 __user *uaddr, int fshared, | |||
1221 | 1222 | ||
1222 | /* add_wait_queue is the barrier after __set_current_state. */ | 1223 | /* add_wait_queue is the barrier after __set_current_state. */ |
1223 | __set_current_state(TASK_INTERRUPTIBLE); | 1224 | __set_current_state(TASK_INTERRUPTIBLE); |
1224 | add_wait_queue(&q.waiters, &wait); | 1225 | add_wait_queue(&q.waiter, &wait); |
1225 | /* | 1226 | /* |
1226 | * !plist_node_empty() is safe here without any lock. | 1227 | * !plist_node_empty() is safe here without any lock. |
1227 | * q.lock_ptr != 0 is not safe, because of ordering against wakeup. | 1228 | * q.lock_ptr != 0 is not safe, because of ordering against wakeup. |