aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/futex.c29
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
693static inline void
694double_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);
839out_put_keys: 848out_put_keys:
840 put_futex_key(fshared, &key2); 849 put_futex_key(fshared, &key2);
841out_put_key1: 850out_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
927out_unlock: 934out_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)