From ff93bca769925a2d8fd7f910cdf543d992e17f07 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Tue, 14 Aug 2018 15:21:31 -0700 Subject: [PATCH] ila: make lockdep happy again Previously, alloc_ila_locks() and bucket_table_alloc() call spin_lock_init() separately, therefore they have two different lock names and lock class keys. However, after commit b893281715ab ("ila: Call library function alloc_bucket_locks") they both call helper alloc_bucket_spinlocks() which now only has one lock name and lock class key. This causes a few bogus lockdep warnings as reported by syzbot. Fix this by making alloc_bucket_locks() a macro and pass declaration name as lock name and a static lock class key inside the macro. Fixes: b893281715ab ("ila: Call library function alloc_bucket_locks") Reported-by: Cc: Tom Herbert Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- include/linux/spinlock.h | 17 ++++++++++++++--- lib/bucket_locks.c | 11 +++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 3190997df9ca..e089157dcf97 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -451,9 +451,20 @@ extern int _atomic_dec_and_lock_irqsave(atomic_t *atomic, spinlock_t *lock, #define atomic_dec_and_lock_irqsave(atomic, lock, flags) \ __cond_lock(lock, _atomic_dec_and_lock_irqsave(atomic, lock, &(flags))) -int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask, - size_t max_size, unsigned int cpu_mult, - gfp_t gfp); +int __alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask, + size_t max_size, unsigned int cpu_mult, + gfp_t gfp, const char *name, + struct lock_class_key *key); + +#define alloc_bucket_spinlocks(locks, lock_mask, max_size, cpu_mult, gfp) \ + ({ \ + static struct lock_class_key key; \ + int ret; \ + \ + ret = __alloc_bucket_spinlocks(locks, lock_mask, max_size, \ + cpu_mult, gfp, #locks, &key); \ + ret; \ + }) void free_bucket_spinlocks(spinlock_t *locks); diff --git a/lib/bucket_locks.c b/lib/bucket_locks.c index ade3ce6c4af6..64b92e1dbace 100644 --- a/lib/bucket_locks.c +++ b/lib/bucket_locks.c @@ -11,8 +11,9 @@ * to a power of 2 to be suitable as a hash table. */ -int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *locks_mask, - size_t max_size, unsigned int cpu_mult, gfp_t gfp) +int __alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *locks_mask, + size_t max_size, unsigned int cpu_mult, gfp_t gfp, + const char *name, struct lock_class_key *key) { spinlock_t *tlocks = NULL; unsigned int i, size; @@ -33,8 +34,10 @@ int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *locks_mask, tlocks = kvmalloc_array(size, sizeof(spinlock_t), gfp); if (!tlocks) return -ENOMEM; - for (i = 0; i < size; i++) + for (i = 0; i < size; i++) { spin_lock_init(&tlocks[i]); + lockdep_init_map(&tlocks[i].dep_map, name, key, 0); + } } *locks = tlocks; @@ -42,7 +45,7 @@ int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *locks_mask, return 0; } -EXPORT_SYMBOL(alloc_bucket_spinlocks); +EXPORT_SYMBOL(__alloc_bucket_spinlocks); void free_bucket_spinlocks(spinlock_t *locks) {