Skip to content

Commit 72dcd50

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
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>
1 parent f214737 commit 72dcd50

File tree

1 file changed

+33
-13
lines changed

1 file changed

+33
-13
lines changed

kernel/locking/lockdep.c

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ module_param(lock_stat, int, 0644);
7474
#define lock_stat 0
7575
#endif
7676

77-
static bool check_data_structure_consistency;
78-
7977
/*
8078
* lockdep_lock: protects the lockdep graph, the hashes and the
8179
* class/list/hash allocators.
@@ -791,6 +789,8 @@ static bool assign_lock_key(struct lockdep_map *lock)
791789
return true;
792790
}
793791

792+
#ifdef CONFIG_DEBUG_LOCKDEP
793+
794794
/* Check whether element @e occurs in list @h */
795795
static bool in_list(struct list_head *e, struct list_head *h)
796796
{
@@ -855,31 +855,31 @@ static bool check_lock_chain_key(struct lock_chain *chain)
855855
* The 'unsigned long long' casts avoid that a compiler warning
856856
* is reported when building tools/lib/lockdep.
857857
*/
858-
if (chain->chain_key != chain_key)
858+
if (chain->chain_key != chain_key) {
859859
printk(KERN_INFO "chain %lld: key %#llx <> %#llx\n",
860860
(unsigned long long)(chain - lock_chains),
861861
(unsigned long long)chain->chain_key,
862862
(unsigned long long)chain_key);
863-
return chain->chain_key == chain_key;
864-
#else
865-
return true;
863+
return false;
864+
}
866865
#endif
866+
return true;
867867
}
868868

869869
static bool in_any_zapped_class_list(struct lock_class *class)
870870
{
871871
struct pending_free *pf;
872872
int i;
873873

874-
for (i = 0, pf = delayed_free.pf; i < ARRAY_SIZE(delayed_free.pf);
875-
i++, pf++)
874+
for (i = 0, pf = delayed_free.pf; i < ARRAY_SIZE(delayed_free.pf); i++, pf++) {
876875
if (in_list(&class->lock_entry, &pf->zapped))
877876
return true;
877+
}
878878

879879
return false;
880880
}
881881

882-
static bool check_data_structures(void)
882+
static bool __check_data_structures(void)
883883
{
884884
struct lock_class *class;
885885
struct lock_chain *chain;
@@ -896,7 +896,6 @@ static bool check_data_structures(void)
896896
printk(KERN_INFO "class %px/%s is not in any class list\n",
897897
class, class->name ? : "(?)");
898898
return false;
899-
return false;
900899
}
901900
}
902901

@@ -953,6 +952,27 @@ static bool check_data_structures(void)
953952
return true;
954953
}
955954

955+
int check_consistency = 0;
956+
module_param(check_consistency, int, 0644);
957+
958+
static void check_data_structures(void)
959+
{
960+
static bool once = false;
961+
962+
if (check_consistency && !once) {
963+
if (!__check_data_structures()) {
964+
once = true;
965+
WARN_ON(once);
966+
}
967+
}
968+
}
969+
970+
#else /* CONFIG_DEBUG_LOCKDEP */
971+
972+
static inline void check_data_structures(void) { }
973+
974+
#endif /* CONFIG_DEBUG_LOCKDEP */
975+
956976
/*
957977
* Initialize the lock_classes[] array elements, the free_lock_classes list
958978
* and also the delayed_free structure.
@@ -4474,10 +4494,11 @@ static void remove_class_from_lock_chain(struct pending_free *pf,
44744494
if (chain_hlocks[i] != class - lock_classes)
44754495
continue;
44764496
/* The code below leaks one chain_hlock[] entry. */
4477-
if (--chain->depth > 0)
4497+
if (--chain->depth > 0) {
44784498
memmove(&chain_hlocks[i], &chain_hlocks[i + 1],
44794499
(chain->base + chain->depth - i) *
44804500
sizeof(chain_hlocks[0]));
4501+
}
44814502
/*
44824503
* Each lock class occurs at most once in a lock chain so once
44834504
* we found a match we can break out of this loop.
@@ -4631,8 +4652,7 @@ static void __free_zapped_classes(struct pending_free *pf)
46314652
{
46324653
struct lock_class *class;
46334654

4634-
if (check_data_structure_consistency)
4635-
WARN_ON_ONCE(!check_data_structures());
4655+
check_data_structures();
46364656

46374657
list_for_each_entry(class, &pf->zapped, lock_entry)
46384658
reinit_class(class);

0 commit comments

Comments
 (0)