diff options
author | Ingo Molnar <mingo@elte.hu> | 2006-07-03 03:25:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-03 18:27:06 -0400 |
commit | 8b8f319fc7f4ab59f567d6a401a62659b3d37007 (patch) | |
tree | f483c5447619de848e2357ba157a1e09277b5c93 | |
parent | f2eace23e924bd3f05aedea4fc505eb5508d2d93 (diff) |
[PATCH] lockdep: annotate futex
Teach special (recursive) locking code to the lock validator. Introduces
double_lock_hb() to unify double- hash-bucket-lock taking.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | kernel/futex.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 15caf93e4a43..1dc98e4dd287 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -607,6 +607,22 @@ static int unlock_futex_pi(u32 __user *uaddr, u32 uval) | |||
607 | } | 607 | } |
608 | 608 | ||
609 | /* | 609 | /* |
610 | * Express the locking dependencies for lockdep: | ||
611 | */ | ||
612 | static inline void | ||
613 | double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) | ||
614 | { | ||
615 | if (hb1 <= hb2) { | ||
616 | spin_lock(&hb1->lock); | ||
617 | if (hb1 < hb2) | ||
618 | spin_lock_nested(&hb2->lock, SINGLE_DEPTH_NESTING); | ||
619 | } else { /* hb1 > hb2 */ | ||
620 | spin_lock(&hb2->lock); | ||
621 | spin_lock_nested(&hb1->lock, SINGLE_DEPTH_NESTING); | ||
622 | } | ||
623 | } | ||
624 | |||
625 | /* | ||
610 | * Wake up all waiters hashed on the physical page that is mapped | 626 | * Wake up all waiters hashed on the physical page that is mapped |
611 | * to this virtual address: | 627 | * to this virtual address: |
612 | */ | 628 | */ |
@@ -674,11 +690,7 @@ retryfull: | |||
674 | hb2 = hash_futex(&key2); | 690 | hb2 = hash_futex(&key2); |
675 | 691 | ||
676 | retry: | 692 | retry: |
677 | if (hb1 < hb2) | 693 | double_lock_hb(hb1, hb2); |
678 | spin_lock(&hb1->lock); | ||
679 | spin_lock(&hb2->lock); | ||
680 | if (hb1 > hb2) | ||
681 | spin_lock(&hb1->lock); | ||
682 | 694 | ||
683 | op_ret = futex_atomic_op_inuser(op, uaddr2); | 695 | op_ret = futex_atomic_op_inuser(op, uaddr2); |
684 | if (unlikely(op_ret < 0)) { | 696 | if (unlikely(op_ret < 0)) { |
@@ -787,11 +799,7 @@ static int futex_requeue(u32 __user *uaddr1, u32 __user *uaddr2, | |||
787 | hb1 = hash_futex(&key1); | 799 | hb1 = hash_futex(&key1); |
788 | hb2 = hash_futex(&key2); | 800 | hb2 = hash_futex(&key2); |
789 | 801 | ||
790 | if (hb1 < hb2) | 802 | double_lock_hb(hb1, hb2); |
791 | spin_lock(&hb1->lock); | ||
792 | spin_lock(&hb2->lock); | ||
793 | if (hb1 > hb2) | ||
794 | spin_lock(&hb1->lock); | ||
795 | 803 | ||
796 | if (likely(cmpval != NULL)) { | 804 | if (likely(cmpval != NULL)) { |
797 | u32 curval; | 805 | u32 curval; |