diff options
author | Peter Zijlstra <peterz@infradead.org> | 2019-02-25 15:56:32 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2019-02-28 07:55:50 +0100 |
commit | 72dcd505e8585857397207f28782c8ba55e553b5 (patch) | |
tree | 64445bcbee51543fbceb0d7614545b3ab7b67f15 /kernel/locking | |
parent | f214737b75b0ee79763b5c058b9d5e83d711348d (diff) | |
download | lwn-72dcd505e8585857397207f28782c8ba55e553b5.tar.gz lwn-72dcd505e8585857397207f28782c8ba55e553b5.zip |
locking/lockdep: Add module_param to enable consistency checks
And move the whole lot under CONFIG_DEBUG_LOCKDEP.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/locking')
-rw-r--r-- | kernel/locking/lockdep.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index c73bc4334bee..fda370ca529c 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -74,8 +74,6 @@ module_param(lock_stat, int, 0644); #define lock_stat 0 #endif -static bool check_data_structure_consistency; - /* * lockdep_lock: protects the lockdep graph, the hashes and the * class/list/hash allocators. @@ -791,6 +789,8 @@ static bool assign_lock_key(struct lockdep_map *lock) return true; } +#ifdef CONFIG_DEBUG_LOCKDEP + /* Check whether element @e occurs in list @h */ static bool in_list(struct list_head *e, struct list_head *h) { @@ -855,15 +855,15 @@ static bool check_lock_chain_key(struct lock_chain *chain) * The 'unsigned long long' casts avoid that a compiler warning * is reported when building tools/lib/lockdep. */ - if (chain->chain_key != chain_key) + if (chain->chain_key != chain_key) { printk(KERN_INFO "chain %lld: key %#llx <> %#llx\n", (unsigned long long)(chain - lock_chains), (unsigned long long)chain->chain_key, (unsigned long long)chain_key); - return chain->chain_key == chain_key; -#else - return true; + return false; + } #endif + return true; } static bool in_any_zapped_class_list(struct lock_class *class) @@ -871,15 +871,15 @@ static bool in_any_zapped_class_list(struct lock_class *class) struct pending_free *pf; int i; - for (i = 0, pf = delayed_free.pf; i < ARRAY_SIZE(delayed_free.pf); - i++, pf++) + for (i = 0, pf = delayed_free.pf; i < ARRAY_SIZE(delayed_free.pf); i++, pf++) { if (in_list(&class->lock_entry, &pf->zapped)) return true; + } return false; } -static bool check_data_structures(void) +static bool __check_data_structures(void) { struct lock_class *class; struct lock_chain *chain; @@ -896,7 +896,6 @@ static bool check_data_structures(void) printk(KERN_INFO "class %px/%s is not in any class list\n", class, class->name ? : "(?)"); return false; - return false; } } @@ -953,6 +952,27 @@ static bool check_data_structures(void) return true; } +int check_consistency = 0; +module_param(check_consistency, int, 0644); + +static void check_data_structures(void) +{ + static bool once = false; + + if (check_consistency && !once) { + if (!__check_data_structures()) { + once = true; + WARN_ON(once); + } + } +} + +#else /* CONFIG_DEBUG_LOCKDEP */ + +static inline void check_data_structures(void) { } + +#endif /* CONFIG_DEBUG_LOCKDEP */ + /* * Initialize the lock_classes[] array elements, the free_lock_classes list * and also the delayed_free structure. @@ -4474,10 +4494,11 @@ static void remove_class_from_lock_chain(struct pending_free *pf, if (chain_hlocks[i] != class - lock_classes) continue; /* The code below leaks one chain_hlock[] entry. */ - if (--chain->depth > 0) + if (--chain->depth > 0) { memmove(&chain_hlocks[i], &chain_hlocks[i + 1], (chain->base + chain->depth - i) * sizeof(chain_hlocks[0])); + } /* * Each lock class occurs at most once in a lock chain so once * we found a match we can break out of this loop. @@ -4631,8 +4652,7 @@ static void __free_zapped_classes(struct pending_free *pf) { struct lock_class *class; - if (check_data_structure_consistency) - WARN_ON_ONCE(!check_data_structures()); + check_data_structures(); list_for_each_entry(class, &pf->zapped, lock_entry) reinit_class(class); |