diff options
-rw-r--r-- | include/linux/bit_spinlock.h | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h index 6b20af0bbb79..7113a32a86ea 100644 --- a/include/linux/bit_spinlock.h +++ b/include/linux/bit_spinlock.h | |||
@@ -18,7 +18,7 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr) | |||
18 | */ | 18 | */ |
19 | preempt_disable(); | 19 | preempt_disable(); |
20 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) | 20 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
21 | while (test_and_set_bit(bitnum, addr)) { | 21 | while (unlikely(test_and_set_bit_lock(bitnum, addr))) { |
22 | while (test_bit(bitnum, addr)) { | 22 | while (test_bit(bitnum, addr)) { |
23 | preempt_enable(); | 23 | preempt_enable(); |
24 | cpu_relax(); | 24 | cpu_relax(); |
@@ -36,7 +36,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) | |||
36 | { | 36 | { |
37 | preempt_disable(); | 37 | preempt_disable(); |
38 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) | 38 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
39 | if (test_and_set_bit(bitnum, addr)) { | 39 | if (unlikely(test_and_set_bit_lock(bitnum, addr))) { |
40 | preempt_enable(); | 40 | preempt_enable(); |
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
@@ -50,10 +50,28 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) | |||
50 | */ | 50 | */ |
51 | static inline void bit_spin_unlock(int bitnum, unsigned long *addr) | 51 | static inline void bit_spin_unlock(int bitnum, unsigned long *addr) |
52 | { | 52 | { |
53 | #ifdef CONFIG_DEBUG_SPINLOCK | ||
54 | BUG_ON(!test_bit(bitnum, addr)); | ||
55 | #endif | ||
53 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) | 56 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
57 | clear_bit_unlock(bitnum, addr); | ||
58 | #endif | ||
59 | preempt_enable(); | ||
60 | __release(bitlock); | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * bit-based spin_unlock() | ||
65 | * non-atomic version, which can be used eg. if the bit lock itself is | ||
66 | * protecting the rest of the flags in the word. | ||
67 | */ | ||
68 | static inline void __bit_spin_unlock(int bitnum, unsigned long *addr) | ||
69 | { | ||
70 | #ifdef CONFIG_DEBUG_SPINLOCK | ||
54 | BUG_ON(!test_bit(bitnum, addr)); | 71 | BUG_ON(!test_bit(bitnum, addr)); |
55 | smp_mb__before_clear_bit(); | 72 | #endif |
56 | clear_bit(bitnum, addr); | 73 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
74 | __clear_bit_unlock(bitnum, addr); | ||
57 | #endif | 75 | #endif |
58 | preempt_enable(); | 76 | preempt_enable(); |
59 | __release(bitlock); | 77 | __release(bitlock); |