diff options
Diffstat (limited to 'kernel/futex.c')
| -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; |
