diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-03-31 16:10:18 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2019-04-30 17:17:03 -0400 |
commit | bf7eaba81d33f206c62d9b1e4234fdfcd0510bc7 (patch) | |
tree | 4a029fbf3dcf1ac528b39d938c75bd70a15d8143 | |
parent | 63f13e5d1073e1d61b8bfbc9053210d93bacbf78 (diff) |
lockdep: debug_check_lock_not_held()
-rw-r--r-- | fs/bcachefs/btree_cache.c | 5 | ||||
-rw-r--r-- | fs/bcachefs/btree_cache.h | 2 | ||||
-rw-r--r-- | fs/bcachefs/btree_iter.c | 2 | ||||
-rw-r--r-- | include/linux/debug_locks.h | 2 | ||||
-rw-r--r-- | kernel/locking/lockdep.c | 18 |
5 files changed, 28 insertions, 1 deletions
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c index 2a20bdef8fd0..74edd09eec93 100644 --- a/fs/bcachefs/btree_cache.c +++ b/fs/bcachefs/btree_cache.c @@ -90,6 +90,8 @@ err: list_move(&b->list, &bc->freed); } +struct lock_class_key bch2_btree_node_lock_key; + static struct btree *btree_node_mem_alloc(struct bch_fs *c, gfp_t gfp) { struct btree *b = kzalloc(sizeof(struct btree), gfp); @@ -97,7 +99,8 @@ static struct btree *btree_node_mem_alloc(struct bch_fs *c, gfp_t gfp) return NULL; bkey_btree_ptr_init(&b->key); - six_lock_init(&b->lock); + __six_lock_init(&b->lock, "&b->lock", &bch2_btree_node_lock_key); + INIT_LIST_HEAD(&b->list); INIT_LIST_HEAD(&b->write_blocked); diff --git a/fs/bcachefs/btree_cache.h b/fs/bcachefs/btree_cache.h index 08e6f2a68ecb..59a0f2f79602 100644 --- a/fs/bcachefs/btree_cache.h +++ b/fs/bcachefs/btree_cache.h @@ -6,6 +6,8 @@ struct btree_iter; +extern struct lock_class_key bch2_btree_node_lock_key; + extern const char * const bch2_btree_ids[]; void bch2_recalc_btree_reserve(struct bch_fs *); diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index 5631f98f3845..18a6ecff155f 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -1888,6 +1888,8 @@ int bch2_trans_unlock(struct btree_trans *trans) iters ^= 1ULL << idx; } + debug_check_lock_not_held(&bch2_btree_node_lock_key); + return ret; } diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h index 257ab3c92cb8..b9718692460d 100644 --- a/include/linux/debug_locks.h +++ b/include/linux/debug_locks.h @@ -7,6 +7,7 @@ #include <linux/bug.h> struct task_struct; +struct lock_class_key; extern int debug_locks __read_mostly; extern int debug_locks_silent __read_mostly; @@ -53,6 +54,7 @@ extern void debug_show_all_locks(void); extern void debug_show_held_locks(struct task_struct *task); extern void debug_check_no_locks_freed(const void *from, unsigned long len); extern void debug_check_no_locks_held(void); +void debug_check_lock_not_held(struct lock_class_key *); #else static inline void debug_show_all_locks(void) { diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 95932333a48b..824b4c2136fa 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -4379,6 +4379,24 @@ void debug_check_no_locks_held(void) } EXPORT_SYMBOL_GPL(debug_check_no_locks_held); +void debug_check_lock_not_held(struct lock_class_key *key) +{ + struct task_struct *p = current; + struct lock_class *class; + unsigned i, j; + + for (i = 0; i < p->lockdep_depth; i++) { + class = hlock_class(p->held_locks + i); + + for (j = 0; j < MAX_LOCKDEP_SUBCLASSES; j++) + if (&key->subkeys[j] == class->key) { + lockdep_print_held_locks(p); + panic("holding lock we shouldn't be\n"); + } + } +} +EXPORT_SYMBOL_GPL(debug_check_lock_not_held); + #ifdef __KERNEL__ void debug_show_all_locks(void) { |