Currently, bit_spin_lock does not use lockdep_map at all. Of course, the lock correctness validator is not supported for bit_spin_lock. This patch makes bit_spin_lock possible to use the validator using CONFIG_BITLOCK_ALLOC.
Signed-off-by: Byungchul Park <byungchul.p...@lge.com> --- include/linux/bit_spinlock.h | 57 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h index 3b5bafc..3f8b013 100644 --- a/include/linux/bit_spinlock.h +++ b/include/linux/bit_spinlock.h @@ -6,13 +6,43 @@ #include <linux/atomic.h> #include <linux/bug.h> +#ifdef CONFIG_BITLOCK_ALLOC +#include <linux/bitlock.h> +#define bit_spin_init(b, a) \ +do { \ + static struct lock_class_key __key; \ + bitlock_init(b, a, #b "@" #a, &__key); \ +} while (0) + +static inline void bit_spin_free(int bitnum, unsigned long *addr) +{ + bitlock_free(bitnum, addr); +} + +static inline void bit_spin_acquire(int bitnum, unsigned long *addr, int try) +{ + struct lockdep_map *map = bitlock_get_map(bitnum, addr, BIT_ACQUIRE); + if (map) + spin_acquire(map, 0, try, _RET_IP_); +} + +static inline void bit_spin_release(int bitnum, unsigned long *addr) +{ + struct lockdep_map *map = bitlock_get_map(bitnum, addr, BIT_RELEASE); + if (map) + spin_release(map, 0, _RET_IP_); +} +#else +static inline void bit_spin_init(int bitnum, unsigned long *addr) {} +static inline void bit_spin_free(int bitnum, unsigned long *addr) {} +static inline void bit_spin_acquire(int bitnum, unsigned long *addr, int try) {} +static inline void bit_spin_release(int bitnum, unsigned long *addr) {} +#endif + /* - * bit-based spin_lock() - * - * Don't use this unless you really need to: spin_lock() and spin_unlock() - * are significantly faster. + * bit-based spin_lock() without lock acquiring */ -static inline void bit_spin_lock(int bitnum, unsigned long *addr) +static inline void do_raw_bit_spin_lock(int bitnum, unsigned long *addr) { /* * Assuming the lock is uncontended, this never enters @@ -21,7 +51,6 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr) * busywait with less bus contention for a good time to * attempt to acquire the lock bit. */ - preempt_disable(); #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) while (unlikely(test_and_set_bit_lock(bitnum, addr))) { preempt_enable(); @@ -35,6 +64,19 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr) } /* + * bit-based spin_lock() + * + * Don't use this unless you really need to: spin_lock() and spin_unlock() + * are significantly faster. + */ +static inline void bit_spin_lock(int bitnum, unsigned long *addr) +{ + preempt_disable(); + bit_spin_acquire(bitnum, addr, 0); + do_raw_bit_spin_lock(bitnum, addr); +} + +/* * Return true if it was acquired */ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) @@ -46,6 +88,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) return 0; } #endif + bit_spin_acquire(bitnum, addr, 1); __acquire(bitlock); return 1; } @@ -55,6 +98,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) */ static inline void bit_spin_unlock(int bitnum, unsigned long *addr) { + bit_spin_release(bitnum, addr); #ifdef CONFIG_DEBUG_SPINLOCK BUG_ON(!test_bit(bitnum, addr)); #endif @@ -72,6 +116,7 @@ static inline void bit_spin_unlock(int bitnum, unsigned long *addr) */ static inline void __bit_spin_unlock(int bitnum, unsigned long *addr) { + bit_spin_release(bitnum, addr); #ifdef CONFIG_DEBUG_SPINLOCK BUG_ON(!test_bit(bitnum, addr)); #endif -- 1.9.1