diff options
author | Darren Hart <dvhltc@us.ibm.com> | 2009-03-12 03:55:46 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-12 06:20:56 -0400 |
commit | de87fcc124a5d4a171aa32707b3265608ebda6e7 (patch) | |
tree | 5ba695dc0b13c7613c8e9306f9703c1b61ef41fc | |
parent | b2d0994b1301fc3a6a89e1889578dac9227840e3 (diff) |
futex: additional (get|put)_futex_key() fixes
Impact: fix races
futex_requeue and futex_lock_pi still had some bad
(get|put)_futex_key() usage. This patch adds the missing
put_futex_keys() and corrects a goto in futex_lock_pi() to avoid
a double get.
Build and boot tested on a 4 way Intel x86_64 workstation.
Passes basic pthread_mutex and PI tests out of
ltp/testcases/realtime.
Signed-off-by: Darren Hart <dvhltc@us.ibm.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
LKML-Reference: <20090312075545.9856.75152.stgit@Aeon>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/futex.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index e6a4d72bca3d..4000454e4d83 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -802,8 +802,10 @@ retry: | |||
802 | 802 | ||
803 | ret = get_user(dummy, uaddr2); | 803 | ret = get_user(dummy, uaddr2); |
804 | if (ret) | 804 | if (ret) |
805 | return ret; | 805 | goto out_put_keys; |
806 | 806 | ||
807 | put_futex_key(fshared, &key2); | ||
808 | put_futex_key(fshared, &key1); | ||
807 | goto retryfull; | 809 | goto retryfull; |
808 | } | 810 | } |
809 | 811 | ||
@@ -878,6 +880,9 @@ retry: | |||
878 | if (hb1 != hb2) | 880 | if (hb1 != hb2) |
879 | spin_unlock(&hb2->lock); | 881 | spin_unlock(&hb2->lock); |
880 | 882 | ||
883 | put_futex_key(fshared, &key2); | ||
884 | put_futex_key(fshared, &key1); | ||
885 | |||
881 | ret = get_user(curval, uaddr1); | 886 | ret = get_user(curval, uaddr1); |
882 | 887 | ||
883 | if (!ret) | 888 | if (!ret) |
@@ -1453,6 +1458,7 @@ retry_locked: | |||
1453 | * exit to complete. | 1458 | * exit to complete. |
1454 | */ | 1459 | */ |
1455 | queue_unlock(&q, hb); | 1460 | queue_unlock(&q, hb); |
1461 | put_futex_key(fshared, &q.key); | ||
1456 | cond_resched(); | 1462 | cond_resched(); |
1457 | goto retry; | 1463 | goto retry; |
1458 | 1464 | ||
@@ -1595,13 +1601,12 @@ uaddr_faulted: | |||
1595 | 1601 | ||
1596 | ret = get_user(uval, uaddr); | 1602 | ret = get_user(uval, uaddr); |
1597 | if (!ret) | 1603 | if (!ret) |
1598 | goto retry; | 1604 | goto retry_unlocked; |
1599 | 1605 | ||
1600 | if (to) | 1606 | goto out_put_key; |
1601 | destroy_hrtimer_on_stack(&to->timer); | ||
1602 | return ret; | ||
1603 | } | 1607 | } |
1604 | 1608 | ||
1609 | |||
1605 | /* | 1610 | /* |
1606 | * Userspace attempted a TID -> 0 atomic transition, and failed. | 1611 | * Userspace attempted a TID -> 0 atomic transition, and failed. |
1607 | * This is the in-kernel slowpath: we look up the PI state (if any), | 1612 | * This is the in-kernel slowpath: we look up the PI state (if any), |
@@ -1705,6 +1710,7 @@ pi_faulted: | |||
1705 | } | 1710 | } |
1706 | 1711 | ||
1707 | ret = get_user(uval, uaddr); | 1712 | ret = get_user(uval, uaddr); |
1713 | put_futex_key(fshared, &key); | ||
1708 | if (!ret) | 1714 | if (!ret) |
1709 | goto retry; | 1715 | goto retry; |
1710 | 1716 | ||