@@ -74,6 +74,8 @@ module_param(lock_stat, int, 0644);
74
74
#define lock_stat 0
75
75
#endif
76
76
77
+ static bool check_data_structure_consistency ;
78
+
77
79
/*
78
80
* lockdep_lock: protects the lockdep graph, the hashes and the
79
81
* class/list/hash allocators.
@@ -775,6 +777,168 @@ static bool assign_lock_key(struct lockdep_map *lock)
775
777
return true;
776
778
}
777
779
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
+
778
942
/*
779
943
* Initialize the lock_classes[] array elements, the free_lock_classes list
780
944
* and also the delayed_free structure.
@@ -4389,6 +4553,9 @@ static void __free_zapped_classes(struct pending_free *pf)
4389
4553
{
4390
4554
struct lock_class * class ;
4391
4555
4556
+ if (check_data_structure_consistency )
4557
+ WARN_ON_ONCE (!check_data_structures ());
4558
+
4392
4559
list_for_each_entry (class , & pf -> zapped , lock_entry )
4393
4560
reinit_class (class );
4394
4561
0 commit comments