diff options
author | Darren Hart <dvhltc@us.ibm.com> | 2009-03-12 03:55:52 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-12 06:20:56 -0400 |
commit | 5eb3dc62fc5986e85715041c23dcf3832812be4b (patch) | |
tree | e8b55b84cc50841ab7f7c87afdcc3d5e419cb4e9 /kernel/futex.c | |
parent | de87fcc124a5d4a171aa32707b3265608ebda6e7 (diff) |
futex: add double_unlock_hb()
Impact: cleanup
The futex code uses double_lock_hb() which locks the hb->lock's
in pointer value order. There is no parallel unlock routine,
and the code unlocks them in name order, ignoring pointer value.
This patch adds double_unlock_hb() to refactor the duplicated
code segments.
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: <20090312075552.9856.48021.stgit@Aeon>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 4000454e4d83..e149545c5cea 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -690,6 +690,19 @@ double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) | |||
690 | } | 690 | } |
691 | } | 691 | } |
692 | 692 | ||
693 | static inline void | ||
694 | double_unlock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) | ||
695 | { | ||
696 | if (hb1 <= hb2) { | ||
697 | spin_unlock(&hb2->lock); | ||
698 | if (hb1 < hb2) | ||
699 | spin_unlock(&hb1->lock); | ||
700 | } else { /* hb1 > hb2 */ | ||
701 | spin_unlock(&hb1->lock); | ||
702 | spin_unlock(&hb2->lock); | ||
703 | } | ||
704 | } | ||
705 | |||
693 | /* | 706 | /* |
694 | * Wake up waiters matching bitset queued on this futex (uaddr). | 707 | * Wake up waiters matching bitset queued on this futex (uaddr). |
695 | */ | 708 | */ |
@@ -767,9 +780,7 @@ retry: | |||
767 | if (unlikely(op_ret < 0)) { | 780 | if (unlikely(op_ret < 0)) { |
768 | u32 dummy; | 781 | u32 dummy; |
769 | 782 | ||
770 | spin_unlock(&hb1->lock); | 783 | double_unlock_hb(hb1, hb2); |
771 | if (hb1 != hb2) | ||
772 | spin_unlock(&hb2->lock); | ||
773 | 784 | ||
774 | #ifndef CONFIG_MMU | 785 | #ifndef CONFIG_MMU |
775 | /* | 786 | /* |
@@ -833,9 +844,7 @@ retry: | |||
833 | ret += op_ret; | 844 | ret += op_ret; |
834 | } | 845 | } |
835 | 846 | ||
836 | spin_unlock(&hb1->lock); | 847 | double_unlock_hb(hb1, hb2); |
837 | if (hb1 != hb2) | ||
838 | spin_unlock(&hb2->lock); | ||
839 | out_put_keys: | 848 | out_put_keys: |
840 | put_futex_key(fshared, &key2); | 849 | put_futex_key(fshared, &key2); |
841 | out_put_key1: | 850 | out_put_key1: |
@@ -876,9 +885,7 @@ retry: | |||
876 | ret = get_futex_value_locked(&curval, uaddr1); | 885 | ret = get_futex_value_locked(&curval, uaddr1); |
877 | 886 | ||
878 | if (unlikely(ret)) { | 887 | if (unlikely(ret)) { |
879 | spin_unlock(&hb1->lock); | 888 | double_unlock_hb(hb1, hb2); |
880 | if (hb1 != hb2) | ||
881 | spin_unlock(&hb2->lock); | ||
882 | 889 | ||
883 | put_futex_key(fshared, &key2); | 890 | put_futex_key(fshared, &key2); |
884 | put_futex_key(fshared, &key1); | 891 | put_futex_key(fshared, &key1); |
@@ -925,9 +932,7 @@ retry: | |||
925 | } | 932 | } |
926 | 933 | ||
927 | out_unlock: | 934 | out_unlock: |
928 | spin_unlock(&hb1->lock); | 935 | double_unlock_hb(hb1, hb2); |
929 | if (hb1 != hb2) | ||
930 | spin_unlock(&hb2->lock); | ||
931 | 936 | ||
932 | /* drop_futex_key_refs() must be called outside the spinlocks. */ | 937 | /* drop_futex_key_refs() must be called outside the spinlocks. */ |
933 | while (--drop_count >= 0) | 938 | while (--drop_count >= 0) |