hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/kernel/locking/lockdep_proc.c
....@@ -24,14 +24,33 @@
2424
2525 #include "lockdep_internals.h"
2626
27
+/*
28
+ * Since iteration of lock_classes is done without holding the lockdep lock,
29
+ * it is not safe to iterate all_lock_classes list directly as the iteration
30
+ * may branch off to free_lock_classes or the zapped list. Iteration is done
31
+ * directly on the lock_classes array by checking the lock_classes_in_use
32
+ * bitmap and max_lock_class_idx.
33
+ */
34
+#define iterate_lock_classes(idx, class) \
35
+ for (idx = 0, class = lock_classes; idx <= max_lock_class_idx; \
36
+ idx++, class++)
37
+
2738 static void *l_next(struct seq_file *m, void *v, loff_t *pos)
2839 {
29
- return seq_list_next(v, &all_lock_classes, pos);
40
+ struct lock_class *class = v;
41
+
42
+ ++class;
43
+ *pos = class - lock_classes;
44
+ return (*pos > max_lock_class_idx) ? NULL : class;
3045 }
3146
3247 static void *l_start(struct seq_file *m, loff_t *pos)
3348 {
34
- return seq_list_start_head(&all_lock_classes, *pos);
49
+ unsigned long idx = *pos;
50
+
51
+ if (idx > max_lock_class_idx)
52
+ return NULL;
53
+ return lock_classes + idx;
3554 }
3655
3756 static void l_stop(struct seq_file *m, void *v)
....@@ -57,18 +76,20 @@
5776
5877 static int l_show(struct seq_file *m, void *v)
5978 {
60
- struct lock_class *class = list_entry(v, struct lock_class, lock_entry);
79
+ struct lock_class *class = v;
6180 struct lock_list *entry;
6281 char usage[LOCK_USAGE_CHARS];
82
+ int idx = class - lock_classes;
6383
64
- if (v == &all_lock_classes) {
84
+ if (v == lock_classes)
6585 seq_printf(m, "all lock classes:\n");
86
+
87
+ if (!test_bit(idx, lock_classes_in_use))
6688 return 0;
67
- }
6889
6990 seq_printf(m, "%p", class->key);
7091 #ifdef CONFIG_DEBUG_LOCKDEP
71
- seq_printf(m, " OPS:%8ld", class->ops);
92
+ seq_printf(m, " OPS:%8ld", debug_class_ops_read(class));
7293 #endif
7394 #ifdef CONFIG_PROVE_LOCKING
7495 seq_printf(m, " FD:%5ld", lockdep_count_forward_deps(class));
....@@ -104,18 +125,18 @@
104125 #ifdef CONFIG_PROVE_LOCKING
105126 static void *lc_start(struct seq_file *m, loff_t *pos)
106127 {
128
+ if (*pos < 0)
129
+ return NULL;
130
+
107131 if (*pos == 0)
108132 return SEQ_START_TOKEN;
109133
110
- if (*pos - 1 < nr_lock_chains)
111
- return lock_chains + (*pos - 1);
112
-
113
- return NULL;
134
+ return lock_chains + (*pos - 1);
114135 }
115136
116137 static void *lc_next(struct seq_file *m, void *v, loff_t *pos)
117138 {
118
- (*pos)++;
139
+ *pos = lockdep_next_lockchain(*pos - 1) + 1;
119140 return lc_start(m, pos);
120141 }
121142
....@@ -128,15 +149,22 @@
128149 struct lock_chain *chain = v;
129150 struct lock_class *class;
130151 int i;
152
+ static const char * const irq_strs[] = {
153
+ [0] = "0",
154
+ [LOCK_CHAIN_HARDIRQ_CONTEXT] = "hardirq",
155
+ [LOCK_CHAIN_SOFTIRQ_CONTEXT] = "softirq",
156
+ [LOCK_CHAIN_SOFTIRQ_CONTEXT|
157
+ LOCK_CHAIN_HARDIRQ_CONTEXT] = "hardirq|softirq",
158
+ };
131159
132160 if (v == SEQ_START_TOKEN) {
133
- if (nr_chain_hlocks > MAX_LOCKDEP_CHAIN_HLOCKS)
161
+ if (!nr_free_chain_hlocks)
134162 seq_printf(m, "(buggered) ");
135163 seq_printf(m, "all lock chains:\n");
136164 return 0;
137165 }
138166
139
- seq_printf(m, "irq_context: %d\n", chain->irq_context);
167
+ seq_printf(m, "irq_context: %s\n", irq_strs[chain->irq_context]);
140168
141169 for (i = 0; i < chain->depth; i++) {
142170 class = lock_chain_get_class(chain, i);
....@@ -211,8 +239,11 @@
211239
212240 #ifdef CONFIG_PROVE_LOCKING
213241 struct lock_class *class;
242
+ unsigned long idx;
214243
215
- list_for_each_entry(class, &all_lock_classes, lock_entry) {
244
+ iterate_lock_classes(idx, class) {
245
+ if (!test_bit(idx, lock_classes_in_use))
246
+ continue;
216247
217248 if (class->usage_mask == 0)
218249 nr_unused++;
....@@ -245,6 +276,7 @@
245276
246277 sum_forward_deps += lockdep_count_forward_deps(class);
247278 }
279
+
248280 #ifdef CONFIG_DEBUG_LOCKDEP
249281 DEBUG_LOCKS_WARN_ON(debug_atomic_read(nr_unused_locks) != nr_unused);
250282 #endif
....@@ -270,9 +302,13 @@
270302
271303 #ifdef CONFIG_PROVE_LOCKING
272304 seq_printf(m, " dependency chains: %11lu [max: %lu]\n",
273
- nr_lock_chains, MAX_LOCKDEP_CHAINS);
274
- seq_printf(m, " dependency chain hlocks: %11d [max: %lu]\n",
275
- nr_chain_hlocks, MAX_LOCKDEP_CHAIN_HLOCKS);
305
+ lock_chain_count(), MAX_LOCKDEP_CHAINS);
306
+ seq_printf(m, " dependency chain hlocks used: %11lu [max: %lu]\n",
307
+ MAX_LOCKDEP_CHAIN_HLOCKS -
308
+ (nr_free_chain_hlocks + nr_lost_chain_hlocks),
309
+ MAX_LOCKDEP_CHAIN_HLOCKS);
310
+ seq_printf(m, " dependency chain hlocks lost: %11u\n",
311
+ nr_lost_chain_hlocks);
276312 #endif
277313
278314 #ifdef CONFIG_TRACE_IRQFLAGS
....@@ -285,6 +321,12 @@
285321 nr_process_chains);
286322 seq_printf(m, " stack-trace entries: %11lu [max: %lu]\n",
287323 nr_stack_trace_entries, MAX_STACK_TRACE_ENTRIES);
324
+#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING)
325
+ seq_printf(m, " number of stack traces: %11llu\n",
326
+ lockdep_stack_trace_count());
327
+ seq_printf(m, " number of stack hash chains: %11llu\n",
328
+ lockdep_stack_hash_count());
329
+#endif
288330 seq_printf(m, " combined max dependencies: %11u\n",
289331 (nr_hardirq_chains + 1) *
290332 (nr_softirq_chains + 1) *
....@@ -326,10 +368,24 @@
326368 seq_printf(m, " max bfs queue depth: %11u\n",
327369 max_bfs_queue_depth);
328370 #endif
371
+ seq_printf(m, " max lock class index: %11lu\n",
372
+ max_lock_class_idx);
329373 lockdep_stats_debug_show(m);
330374 seq_printf(m, " debug_locks: %11u\n",
331375 debug_locks);
332376
377
+ /*
378
+ * Zappped classes and lockdep data buffers reuse statistics.
379
+ */
380
+ seq_puts(m, "\n");
381
+ seq_printf(m, " zapped classes: %11lu\n",
382
+ nr_zapped_classes);
383
+#ifdef CONFIG_PROVE_LOCKING
384
+ seq_printf(m, " zapped lock chains: %11lu\n",
385
+ nr_zapped_lock_chains);
386
+ seq_printf(m, " large chain blocks: %11u\n",
387
+ nr_large_chain_blocks);
388
+#endif
333389 return 0;
334390 }
335391
....@@ -399,7 +455,7 @@
399455
400456 static void seq_stats(struct seq_file *m, struct lock_stat_data *data)
401457 {
402
- struct lockdep_subclass_key *ckey;
458
+ const struct lockdep_subclass_key *ckey;
403459 struct lock_class_stats *stats;
404460 struct lock_class *class;
405461 const char *cname;
....@@ -591,12 +647,16 @@
591647 if (!res) {
592648 struct lock_stat_data *iter = data->stats;
593649 struct seq_file *m = file->private_data;
650
+ unsigned long idx;
594651
595
- list_for_each_entry(class, &all_lock_classes, lock_entry) {
652
+ iterate_lock_classes(idx, class) {
653
+ if (!test_bit(idx, lock_classes_in_use))
654
+ continue;
596655 iter->class = class;
597656 iter->stats = lock_stats(class);
598657 iter++;
599658 }
659
+
600660 data->iter_end = iter;
601661
602662 sort(data->stats, data->iter_end - data->stats,
....@@ -614,6 +674,7 @@
614674 size_t count, loff_t *ppos)
615675 {
616676 struct lock_class *class;
677
+ unsigned long idx;
617678 char c;
618679
619680 if (count) {
....@@ -623,8 +684,11 @@
623684 if (c != '0')
624685 return count;
625686
626
- list_for_each_entry(class, &all_lock_classes, lock_entry)
687
+ iterate_lock_classes(idx, class) {
688
+ if (!test_bit(idx, lock_classes_in_use))
689
+ continue;
627690 clear_lock_stats(class);
691
+ }
628692 }
629693 return count;
630694 }
....@@ -637,12 +701,12 @@
637701 return seq_release(inode, file);
638702 }
639703
640
-static const struct file_operations proc_lock_stat_operations = {
641
- .open = lock_stat_open,
642
- .write = lock_stat_write,
643
- .read = seq_read,
644
- .llseek = seq_lseek,
645
- .release = lock_stat_release,
704
+static const struct proc_ops lock_stat_proc_ops = {
705
+ .proc_open = lock_stat_open,
706
+ .proc_write = lock_stat_write,
707
+ .proc_read = seq_read,
708
+ .proc_lseek = seq_lseek,
709
+ .proc_release = lock_stat_release,
646710 };
647711 #endif /* CONFIG_LOCK_STAT */
648712
....@@ -654,8 +718,7 @@
654718 #endif
655719 proc_create_single("lockdep_stats", S_IRUSR, NULL, lockdep_stats_show);
656720 #ifdef CONFIG_LOCK_STAT
657
- proc_create("lock_stat", S_IRUSR | S_IWUSR, NULL,
658
- &proc_lock_stat_operations);
721
+ proc_create("lock_stat", S_IRUSR | S_IWUSR, NULL, &lock_stat_proc_ops);
659722 #endif
660723
661724 return 0;