Skip to content

Commit b526b2e

Browse files
bvanasscheIngo Molnar
authored andcommitted
locking/lockdep: Check data structure consistency
Debugging lockdep data structure inconsistencies is challenging. Add code that verifies data structure consistency at runtime. That code is disabled by default because it is very CPU intensive. Signed-off-by: Bart Van Assche <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Johannes Berg <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Paul E. McKenney <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Waiman Long <[email protected]> Cc: Will Deacon <[email protected]> Cc: [email protected] Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent de4643a commit b526b2e

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

kernel/locking/lockdep.c

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

77+
static bool check_data_structure_consistency;
78+
7779
/*
7880
* lockdep_lock: protects the lockdep graph, the hashes and the
7981
* class/list/hash allocators.
@@ -775,6 +777,168 @@ static bool assign_lock_key(struct lockdep_map *lock)
775777
return true;
776778
}
777779

780+
/* Check whether element @e occurs in list @h */
781+
static bool in_list(struct list_head *e, struct list_head *h)
782+
{
783+
struct list_head *f;
784+
785+
list_for_each(f, h) {
786+
if (e == f)
787+
return true;
788+
}
789+
790+
return false;
791+
}
792+
793+
/*
794+
* Check whether entry @e occurs in any of the locks_after or locks_before
795+
* lists.
796+
*/
797+
static bool in_any_class_list(struct list_head *e)
798+
{
799+
struct lock_class *class;
800+
int i;
801+
802+
for (i = 0; i < ARRAY_SIZE(lock_classes); i++) {
803+
class = &lock_classes[i];
804+
if (in_list(e, &class->locks_after) ||
805+
in_list(e, &class->locks_before))
806+
return true;
807+
}
808+
return false;
809+
}
810+
811+
static bool class_lock_list_valid(struct lock_class *c, struct list_head *h)
812+
{
813+
struct lock_list *e;
814+
815+
list_for_each_entry(e, h, entry) {
816+
if (e->links_to != c) {
817+
printk(KERN_INFO "class %s: mismatch for lock entry %ld; class %s <> %s",
818+
c->name ? : "(?)",
819+
(unsigned long)(e - list_entries),
820+
e->links_to && e->links_to->name ?
821+
e->links_to->name : "(?)",
822+
e->class && e->class->name ? e->class->name :
823+
"(?)");
824+
return false;
825+
}
826+
}
827+
return true;
828+
}
829+
830+
static u16 chain_hlocks[];
831+
832+
static bool check_lock_chain_key(struct lock_chain *chain)
833+
{
834+
#ifdef CONFIG_PROVE_LOCKING
835+
u64 chain_key = 0;
836+
int i;
837+
838+
for (i = chain->base; i < chain->base + chain->depth; i++)
839+
chain_key = iterate_chain_key(chain_key, chain_hlocks[i] + 1);
840+
/*
841+
* The 'unsigned long long' casts avoid that a compiler warning
842+
* is reported when building tools/lib/lockdep.
843+
*/
844+
if (chain->chain_key != chain_key)
845+
printk(KERN_INFO "chain %lld: key %#llx <> %#llx\n",
846+
(unsigned long long)(chain - lock_chains),
847+
(unsigned long long)chain->chain_key,
848+
(unsigned long long)chain_key);
849+
return chain->chain_key == chain_key;
850+
#else
851+
return true;
852+
#endif
853+
}
854+
855+
static bool in_any_zapped_class_list(struct lock_class *class)
856+
{
857+
struct pending_free *pf;
858+
int i;
859+
860+
for (i = 0, pf = delayed_free.pf; i < ARRAY_SIZE(delayed_free.pf);
861+
i++, pf++)
862+
if (in_list(&class->lock_entry, &pf->zapped))
863+
return true;
864+
865+
return false;
866+
}
867+
868+
static bool check_data_structures(void)
869+
{
870+
struct lock_class *class;
871+
struct lock_chain *chain;
872+
struct hlist_head *head;
873+
struct lock_list *e;
874+
int i;
875+
876+
/* Check whether all classes occur in a lock list. */
877+
for (i = 0; i < ARRAY_SIZE(lock_classes); i++) {
878+
class = &lock_classes[i];
879+
if (!in_list(&class->lock_entry, &all_lock_classes) &&
880+
!in_list(&class->lock_entry, &free_lock_classes) &&
881+
!in_any_zapped_class_list(class)) {
882+
printk(KERN_INFO "class %px/%s is not in any class list\n",
883+
class, class->name ? : "(?)");
884+
return false;
885+
return false;
886+
}
887+
}
888+
889+
/* Check whether all classes have valid lock lists. */
890+
for (i = 0; i < ARRAY_SIZE(lock_classes); i++) {
891+
class = &lock_classes[i];
892+
if (!class_lock_list_valid(class, &class->locks_before))
893+
return false;
894+
if (!class_lock_list_valid(class, &class->locks_after))
895+
return false;
896+
}
897+
898+
/* Check the chain_key of all lock chains. */
899+
for (i = 0; i < ARRAY_SIZE(chainhash_table); i++) {
900+
head = chainhash_table + i;
901+
hlist_for_each_entry_rcu(chain, head, entry) {
902+
if (!check_lock_chain_key(chain))
903+
return false;
904+
}
905+
}
906+
907+
/*
908+
* Check whether all list entries that are in use occur in a class
909+
* lock list.
910+
*/
911+
for_each_set_bit(i, list_entries_in_use, ARRAY_SIZE(list_entries)) {
912+
e = list_entries + i;
913+
if (!in_any_class_list(&e->entry)) {
914+
printk(KERN_INFO "list entry %d is not in any class list; class %s <> %s\n",
915+
(unsigned int)(e - list_entries),
916+
e->class->name ? : "(?)",
917+
e->links_to->name ? : "(?)");
918+
return false;
919+
}
920+
}
921+
922+
/*
923+
* Check whether all list entries that are not in use do not occur in
924+
* a class lock list.
925+
*/
926+
for_each_clear_bit(i, list_entries_in_use, ARRAY_SIZE(list_entries)) {
927+
e = list_entries + i;
928+
if (in_any_class_list(&e->entry)) {
929+
printk(KERN_INFO "list entry %d occurs in a class list; class %s <> %s\n",
930+
(unsigned int)(e - list_entries),
931+
e->class && e->class->name ? e->class->name :
932+
"(?)",
933+
e->links_to && e->links_to->name ?
934+
e->links_to->name : "(?)");
935+
return false;
936+
}
937+
}
938+
939+
return true;
940+
}
941+
778942
/*
779943
* Initialize the lock_classes[] array elements, the free_lock_classes list
780944
* and also the delayed_free structure.
@@ -4389,6 +4553,9 @@ static void __free_zapped_classes(struct pending_free *pf)
43894553
{
43904554
struct lock_class *class;
43914555

4556+
if (check_data_structure_consistency)
4557+
WARN_ON_ONCE(!check_data_structures());
4558+
43924559
list_for_each_entry(class, &pf->zapped, lock_entry)
43934560
reinit_class(class);
43944561

0 commit comments

Comments
 (0)