aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
authorDarren Hart <dvhltc@us.ibm.com>2009-04-08 02:23:50 -0400
committerThomas Gleixner <tglx@linutronix.de>2009-04-08 06:58:20 -0400
commitbab5bc9e857638880facef76e4b4c3fa807f8c73 (patch)
tree8129a3fc18f770021bfe202900ecc2cb144d18c7 /kernel/futex.c
parent52400ba946759af28442dee6265c5c0180ac7122 (diff)
futex: fixup unlocked requeue pi case
Thomas's testing caught a problem when the requeue target futex is unowned and multiple tasks are requeued to it. This patch ensures the FUTEX_WAITERS bit gets set if futex_requeue() will requeue one or more tasks in addition to the one acquiring the lock. Signed-off-by: Darren Hart <dvhltc@us.ibm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 185c981d89e3..041bf3ac4be9 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -565,12 +565,14 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
565 565
566/** 566/**
567 * futex_lock_pi_atomic() - atomic work required to acquire a pi aware futex 567 * futex_lock_pi_atomic() - atomic work required to acquire a pi aware futex
568 * @uaddr: the pi futex user address 568 * @uaddr: the pi futex user address
569 * @hb: the pi futex hash bucket 569 * @hb: the pi futex hash bucket
570 * @key: the futex key associated with uaddr and hb 570 * @key: the futex key associated with uaddr and hb
571 * @ps: the pi_state pointer where we store the result of the lookup 571 * @ps: the pi_state pointer where we store the result of the
572 * @task: the task to perform the atomic lock work for. This will be 572 * lookup
573 * "current" except in the case of requeue pi. 573 * @task: the task to perform the atomic lock work for. This will
574 * be "current" except in the case of requeue pi.
575 * @set_waiters: force setting the FUTEX_WAITERS bit (1) or not (0)
574 * 576 *
575 * Returns: 577 * Returns:
576 * 0 - ready to wait 578 * 0 - ready to wait
@@ -582,7 +584,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
582static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, 584static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb,
583 union futex_key *key, 585 union futex_key *key,
584 struct futex_pi_state **ps, 586 struct futex_pi_state **ps,
585 struct task_struct *task) 587 struct task_struct *task, int set_waiters)
586{ 588{
587 int lock_taken, ret, ownerdied = 0; 589 int lock_taken, ret, ownerdied = 0;
588 u32 uval, newval, curval; 590 u32 uval, newval, curval;
@@ -596,6 +598,8 @@ retry:
596 * the locks. It will most likely not succeed. 598 * the locks. It will most likely not succeed.
597 */ 599 */
598 newval = task_pid_vnr(task); 600 newval = task_pid_vnr(task);
601 if (set_waiters)
602 newval |= FUTEX_WAITERS;
599 603
600 curval = cmpxchg_futex_value_locked(uaddr, 0, newval); 604 curval = cmpxchg_futex_value_locked(uaddr, 0, newval);
601 605
@@ -1004,14 +1008,18 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key)
1004 1008
1005/** 1009/**
1006 * futex_proxy_trylock_atomic() - Attempt an atomic lock for the top waiter 1010 * futex_proxy_trylock_atomic() - Attempt an atomic lock for the top waiter
1007 * @pifutex: the user address of the to futex 1011 * @pifutex: the user address of the to futex
1008 * @hb1: the from futex hash bucket, must be locked by the caller 1012 * @hb1: the from futex hash bucket, must be locked by the caller
1009 * @hb2: the to futex hash bucket, must be locked by the caller 1013 * @hb2: the to futex hash bucket, must be locked by the caller
1010 * @key1: the from futex key 1014 * @key1: the from futex key
1011 * @key2: the to futex key 1015 * @key2: the to futex key
1016 * @ps: address to store the pi_state pointer
1017 * @set_waiters: force setting the FUTEX_WAITERS bit (1) or not (0)
1012 * 1018 *
1013 * Try and get the lock on behalf of the top waiter if we can do it atomically. 1019 * Try and get the lock on behalf of the top waiter if we can do it atomically.
1014 * Wake the top waiter if we succeed. hb1 and hb2 must be held by the caller. 1020 * Wake the top waiter if we succeed. If the caller specified set_waiters,
1021 * then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit.
1022 * hb1 and hb2 must be held by the caller.
1015 * 1023 *
1016 * Returns: 1024 * Returns:
1017 * 0 - failed to acquire the lock atomicly 1025 * 0 - failed to acquire the lock atomicly
@@ -1022,15 +1030,23 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
1022 struct futex_hash_bucket *hb1, 1030 struct futex_hash_bucket *hb1,
1023 struct futex_hash_bucket *hb2, 1031 struct futex_hash_bucket *hb2,
1024 union futex_key *key1, union futex_key *key2, 1032 union futex_key *key1, union futex_key *key2,
1025 struct futex_pi_state **ps) 1033 struct futex_pi_state **ps, int set_waiters)
1026{ 1034{
1027 struct futex_q *top_waiter; 1035 struct futex_q *top_waiter = NULL;
1028 u32 curval; 1036 u32 curval;
1029 int ret; 1037 int ret;
1030 1038
1031 if (get_futex_value_locked(&curval, pifutex)) 1039 if (get_futex_value_locked(&curval, pifutex))
1032 return -EFAULT; 1040 return -EFAULT;
1033 1041
1042 /*
1043 * Find the top_waiter and determine if there are additional waiters.
1044 * If the caller intends to requeue more than 1 waiter to pifutex,
1045 * force futex_lock_pi_atomic() to set the FUTEX_WAITERS bit now,
1046 * as we have means to handle the possible fault. If not, don't set
1047 * the bit unecessarily as it will force the subsequent unlock to enter
1048 * the kernel.
1049 */
1034 top_waiter = futex_top_waiter(hb1, key1); 1050 top_waiter = futex_top_waiter(hb1, key1);
1035 1051
1036 /* There are no waiters, nothing for us to do. */ 1052 /* There are no waiters, nothing for us to do. */
@@ -1038,10 +1054,12 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
1038 return 0; 1054 return 0;
1039 1055
1040 /* 1056 /*
1041 * Either take the lock for top_waiter or set the FUTEX_WAITERS bit. 1057 * Try to take the lock for top_waiter. Set the FUTEX_WAITERS bit in
1042 * The pi_state is returned in ps in contended cases. 1058 * the contended case or if set_waiters is 1. The pi_state is returned
1059 * in ps in contended cases.
1043 */ 1060 */
1044 ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task); 1061 ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task,
1062 set_waiters);
1045 if (ret == 1) 1063 if (ret == 1)
1046 requeue_pi_wake_futex(top_waiter, key2); 1064 requeue_pi_wake_futex(top_waiter, key2);
1047 1065
@@ -1146,9 +1164,14 @@ retry_private:
1146 } 1164 }
1147 1165
1148 if (requeue_pi && (task_count - nr_wake < nr_requeue)) { 1166 if (requeue_pi && (task_count - nr_wake < nr_requeue)) {
1149 /* Attempt to acquire uaddr2 and wake the top_waiter. */ 1167 /*
1168 * Attempt to acquire uaddr2 and wake the top waiter. If we
1169 * intend to requeue waiters, force setting the FUTEX_WAITERS
1170 * bit. We force this here where we are able to easily handle
1171 * faults rather in the requeue loop below.
1172 */
1150 ret = futex_proxy_trylock_atomic(uaddr2, hb1, hb2, &key1, 1173 ret = futex_proxy_trylock_atomic(uaddr2, hb1, hb2, &key1,
1151 &key2, &pi_state); 1174 &key2, &pi_state, nr_requeue);
1152 1175
1153 /* 1176 /*
1154 * At this point the top_waiter has either taken uaddr2 or is 1177 * At this point the top_waiter has either taken uaddr2 or is
@@ -1810,7 +1833,7 @@ retry:
1810retry_private: 1833retry_private:
1811 hb = queue_lock(&q); 1834 hb = queue_lock(&q);
1812 1835
1813 ret = futex_lock_pi_atomic(uaddr, hb, &q.key, &q.pi_state, current); 1836 ret = futex_lock_pi_atomic(uaddr, hb, &q.key, &q.pi_state, current, 0);
1814 if (unlikely(ret)) { 1837 if (unlikely(ret)) {
1815 switch (ret) { 1838 switch (ret) {
1816 case 1: 1839 case 1: