From e89b6d5bae3c74aa4abb3c0a74d2fe6bbb822b41 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 3 Jul 2006 00:25:05 -0700 Subject: [PATCH] --- yaml --- r: 31815 b: refs/heads/master c: 8b8f319fc7f4ab59f567d6a401a62659b3d37007 h: refs/heads/master i: 31813: 5d53cc023036178996a9cf2965103a6e20ca02ec 31811: ac748fcfa555573aea1ad3a3ae8679e32b00667b 31807: 751c8fe3e201192bd7ade00fba0d6d8be5394a8d v: v3 --- [refs] | 2 +- trunk/kernel/futex.c | 28 ++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index a9e461266691..12c4ad84f230 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f2eace23e924bd3f05aedea4fc505eb5508d2d93 +refs/heads/master: 8b8f319fc7f4ab59f567d6a401a62659b3d37007 diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 15caf93e4a43..1dc98e4dd287 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -606,6 +606,22 @@ static int unlock_futex_pi(u32 __user *uaddr, u32 uval) return 0; } +/* + * Express the locking dependencies for lockdep: + */ +static inline void +double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) +{ + if (hb1 <= hb2) { + spin_lock(&hb1->lock); + if (hb1 < hb2) + spin_lock_nested(&hb2->lock, SINGLE_DEPTH_NESTING); + } else { /* hb1 > hb2 */ + spin_lock(&hb2->lock); + spin_lock_nested(&hb1->lock, SINGLE_DEPTH_NESTING); + } +} + /* * Wake up all waiters hashed on the physical page that is mapped * to this virtual address: @@ -674,11 +690,7 @@ futex_wake_op(u32 __user *uaddr1, u32 __user *uaddr2, hb2 = hash_futex(&key2); retry: - if (hb1 < hb2) - spin_lock(&hb1->lock); - spin_lock(&hb2->lock); - if (hb1 > hb2) - spin_lock(&hb1->lock); + double_lock_hb(hb1, hb2); op_ret = futex_atomic_op_inuser(op, uaddr2); if (unlikely(op_ret < 0)) { @@ -787,11 +799,7 @@ static int futex_requeue(u32 __user *uaddr1, u32 __user *uaddr2, hb1 = hash_futex(&key1); hb2 = hash_futex(&key2); - if (hb1 < hb2) - spin_lock(&hb1->lock); - spin_lock(&hb2->lock); - if (hb1 > hb2) - spin_lock(&hb1->lock); + double_lock_hb(hb1, hb2); if (likely(cmpval != NULL)) { u32 curval;