ia64/linux-2.6.18-xen.hg

annotate kernel/lockdep_proc.c @ 912:dd42cdb0ab89

[IA64] Build blktap2 driver by default in x86 builds.

add CONFIG_XEN_BLKDEV_TAP2=y to buildconfigs/linux-defconfig_xen_ia64.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Jun 29 12:09:16 2009 +0900 (2009-06-29)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * kernel/lockdep_proc.c
ian@0 3 *
ian@0 4 * Runtime locking correctness validator
ian@0 5 *
ian@0 6 * Started by Ingo Molnar:
ian@0 7 *
ian@0 8 * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
ian@0 9 *
ian@0 10 * Code for /proc/lockdep and /proc/lockdep_stats:
ian@0 11 *
ian@0 12 */
ian@0 13 #include <linux/sched.h>
ian@0 14 #include <linux/module.h>
ian@0 15 #include <linux/proc_fs.h>
ian@0 16 #include <linux/seq_file.h>
ian@0 17 #include <linux/kallsyms.h>
ian@0 18 #include <linux/debug_locks.h>
ian@0 19
ian@0 20 #include "lockdep_internals.h"
ian@0 21
ian@0 22 static void *l_next(struct seq_file *m, void *v, loff_t *pos)
ian@0 23 {
ian@0 24 struct lock_class *class = v;
ian@0 25
ian@0 26 (*pos)++;
ian@0 27
ian@0 28 if (class->lock_entry.next != &all_lock_classes)
ian@0 29 class = list_entry(class->lock_entry.next, struct lock_class,
ian@0 30 lock_entry);
ian@0 31 else
ian@0 32 class = NULL;
ian@0 33 m->private = class;
ian@0 34
ian@0 35 return class;
ian@0 36 }
ian@0 37
ian@0 38 static void *l_start(struct seq_file *m, loff_t *pos)
ian@0 39 {
ian@0 40 struct lock_class *class = m->private;
ian@0 41
ian@0 42 if (&class->lock_entry == all_lock_classes.next)
ian@0 43 seq_printf(m, "all lock classes:\n");
ian@0 44
ian@0 45 return class;
ian@0 46 }
ian@0 47
ian@0 48 static void l_stop(struct seq_file *m, void *v)
ian@0 49 {
ian@0 50 }
ian@0 51
ian@0 52 static unsigned long count_forward_deps(struct lock_class *class)
ian@0 53 {
ian@0 54 struct lock_list *entry;
ian@0 55 unsigned long ret = 1;
ian@0 56
ian@0 57 /*
ian@0 58 * Recurse this class's dependency list:
ian@0 59 */
ian@0 60 list_for_each_entry(entry, &class->locks_after, entry)
ian@0 61 ret += count_forward_deps(entry->class);
ian@0 62
ian@0 63 return ret;
ian@0 64 }
ian@0 65
ian@0 66 static unsigned long count_backward_deps(struct lock_class *class)
ian@0 67 {
ian@0 68 struct lock_list *entry;
ian@0 69 unsigned long ret = 1;
ian@0 70
ian@0 71 /*
ian@0 72 * Recurse this class's dependency list:
ian@0 73 */
ian@0 74 list_for_each_entry(entry, &class->locks_before, entry)
ian@0 75 ret += count_backward_deps(entry->class);
ian@0 76
ian@0 77 return ret;
ian@0 78 }
ian@0 79
ian@0 80 static int l_show(struct seq_file *m, void *v)
ian@0 81 {
ian@0 82 unsigned long nr_forward_deps, nr_backward_deps;
ian@0 83 struct lock_class *class = m->private;
ian@0 84 char str[128], c1, c2, c3, c4;
ian@0 85 const char *name;
ian@0 86
ian@0 87 seq_printf(m, "%p", class->key);
ian@0 88 #ifdef CONFIG_DEBUG_LOCKDEP
ian@0 89 seq_printf(m, " OPS:%8ld", class->ops);
ian@0 90 #endif
ian@0 91 nr_forward_deps = count_forward_deps(class);
ian@0 92 seq_printf(m, " FD:%5ld", nr_forward_deps);
ian@0 93
ian@0 94 nr_backward_deps = count_backward_deps(class);
ian@0 95 seq_printf(m, " BD:%5ld", nr_backward_deps);
ian@0 96
ian@0 97 get_usage_chars(class, &c1, &c2, &c3, &c4);
ian@0 98 seq_printf(m, " %c%c%c%c", c1, c2, c3, c4);
ian@0 99
ian@0 100 name = class->name;
ian@0 101 if (!name) {
ian@0 102 name = __get_key_name(class->key, str);
ian@0 103 seq_printf(m, ": %s", name);
ian@0 104 } else{
ian@0 105 seq_printf(m, ": %s", name);
ian@0 106 if (class->name_version > 1)
ian@0 107 seq_printf(m, "#%d", class->name_version);
ian@0 108 if (class->subclass)
ian@0 109 seq_printf(m, "/%d", class->subclass);
ian@0 110 }
ian@0 111 seq_puts(m, "\n");
ian@0 112
ian@0 113 return 0;
ian@0 114 }
ian@0 115
ian@0 116 static struct seq_operations lockdep_ops = {
ian@0 117 .start = l_start,
ian@0 118 .next = l_next,
ian@0 119 .stop = l_stop,
ian@0 120 .show = l_show,
ian@0 121 };
ian@0 122
ian@0 123 static int lockdep_open(struct inode *inode, struct file *file)
ian@0 124 {
ian@0 125 int res = seq_open(file, &lockdep_ops);
ian@0 126 if (!res) {
ian@0 127 struct seq_file *m = file->private_data;
ian@0 128
ian@0 129 if (!list_empty(&all_lock_classes))
ian@0 130 m->private = list_entry(all_lock_classes.next,
ian@0 131 struct lock_class, lock_entry);
ian@0 132 else
ian@0 133 m->private = NULL;
ian@0 134 }
ian@0 135 return res;
ian@0 136 }
ian@0 137
ian@0 138 static struct file_operations proc_lockdep_operations = {
ian@0 139 .open = lockdep_open,
ian@0 140 .read = seq_read,
ian@0 141 .llseek = seq_lseek,
ian@0 142 .release = seq_release,
ian@0 143 };
ian@0 144
ian@0 145 static void lockdep_stats_debug_show(struct seq_file *m)
ian@0 146 {
ian@0 147 #ifdef CONFIG_DEBUG_LOCKDEP
ian@0 148 unsigned int hi1 = debug_atomic_read(&hardirqs_on_events),
ian@0 149 hi2 = debug_atomic_read(&hardirqs_off_events),
ian@0 150 hr1 = debug_atomic_read(&redundant_hardirqs_on),
ian@0 151 hr2 = debug_atomic_read(&redundant_hardirqs_off),
ian@0 152 si1 = debug_atomic_read(&softirqs_on_events),
ian@0 153 si2 = debug_atomic_read(&softirqs_off_events),
ian@0 154 sr1 = debug_atomic_read(&redundant_softirqs_on),
ian@0 155 sr2 = debug_atomic_read(&redundant_softirqs_off);
ian@0 156
ian@0 157 seq_printf(m, " chain lookup misses: %11u\n",
ian@0 158 debug_atomic_read(&chain_lookup_misses));
ian@0 159 seq_printf(m, " chain lookup hits: %11u\n",
ian@0 160 debug_atomic_read(&chain_lookup_hits));
ian@0 161 seq_printf(m, " cyclic checks: %11u\n",
ian@0 162 debug_atomic_read(&nr_cyclic_checks));
ian@0 163 seq_printf(m, " cyclic-check recursions: %11u\n",
ian@0 164 debug_atomic_read(&nr_cyclic_check_recursions));
ian@0 165 seq_printf(m, " find-mask forwards checks: %11u\n",
ian@0 166 debug_atomic_read(&nr_find_usage_forwards_checks));
ian@0 167 seq_printf(m, " find-mask forwards recursions: %11u\n",
ian@0 168 debug_atomic_read(&nr_find_usage_forwards_recursions));
ian@0 169 seq_printf(m, " find-mask backwards checks: %11u\n",
ian@0 170 debug_atomic_read(&nr_find_usage_backwards_checks));
ian@0 171 seq_printf(m, " find-mask backwards recursions:%11u\n",
ian@0 172 debug_atomic_read(&nr_find_usage_backwards_recursions));
ian@0 173
ian@0 174 seq_printf(m, " hardirq on events: %11u\n", hi1);
ian@0 175 seq_printf(m, " hardirq off events: %11u\n", hi2);
ian@0 176 seq_printf(m, " redundant hardirq ons: %11u\n", hr1);
ian@0 177 seq_printf(m, " redundant hardirq offs: %11u\n", hr2);
ian@0 178 seq_printf(m, " softirq on events: %11u\n", si1);
ian@0 179 seq_printf(m, " softirq off events: %11u\n", si2);
ian@0 180 seq_printf(m, " redundant softirq ons: %11u\n", sr1);
ian@0 181 seq_printf(m, " redundant softirq offs: %11u\n", sr2);
ian@0 182 #endif
ian@0 183 }
ian@0 184
ian@0 185 static int lockdep_stats_show(struct seq_file *m, void *v)
ian@0 186 {
ian@0 187 struct lock_class *class;
ian@0 188 unsigned long nr_unused = 0, nr_uncategorized = 0,
ian@0 189 nr_irq_safe = 0, nr_irq_unsafe = 0,
ian@0 190 nr_softirq_safe = 0, nr_softirq_unsafe = 0,
ian@0 191 nr_hardirq_safe = 0, nr_hardirq_unsafe = 0,
ian@0 192 nr_irq_read_safe = 0, nr_irq_read_unsafe = 0,
ian@0 193 nr_softirq_read_safe = 0, nr_softirq_read_unsafe = 0,
ian@0 194 nr_hardirq_read_safe = 0, nr_hardirq_read_unsafe = 0,
ian@0 195 sum_forward_deps = 0, factor = 0;
ian@0 196
ian@0 197 list_for_each_entry(class, &all_lock_classes, lock_entry) {
ian@0 198
ian@0 199 if (class->usage_mask == 0)
ian@0 200 nr_unused++;
ian@0 201 if (class->usage_mask == LOCKF_USED)
ian@0 202 nr_uncategorized++;
ian@0 203 if (class->usage_mask & LOCKF_USED_IN_IRQ)
ian@0 204 nr_irq_safe++;
ian@0 205 if (class->usage_mask & LOCKF_ENABLED_IRQS)
ian@0 206 nr_irq_unsafe++;
ian@0 207 if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ)
ian@0 208 nr_softirq_safe++;
ian@0 209 if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS)
ian@0 210 nr_softirq_unsafe++;
ian@0 211 if (class->usage_mask & LOCKF_USED_IN_HARDIRQ)
ian@0 212 nr_hardirq_safe++;
ian@0 213 if (class->usage_mask & LOCKF_ENABLED_HARDIRQS)
ian@0 214 nr_hardirq_unsafe++;
ian@0 215 if (class->usage_mask & LOCKF_USED_IN_IRQ_READ)
ian@0 216 nr_irq_read_safe++;
ian@0 217 if (class->usage_mask & LOCKF_ENABLED_IRQS_READ)
ian@0 218 nr_irq_read_unsafe++;
ian@0 219 if (class->usage_mask & LOCKF_USED_IN_SOFTIRQ_READ)
ian@0 220 nr_softirq_read_safe++;
ian@0 221 if (class->usage_mask & LOCKF_ENABLED_SOFTIRQS_READ)
ian@0 222 nr_softirq_read_unsafe++;
ian@0 223 if (class->usage_mask & LOCKF_USED_IN_HARDIRQ_READ)
ian@0 224 nr_hardirq_read_safe++;
ian@0 225 if (class->usage_mask & LOCKF_ENABLED_HARDIRQS_READ)
ian@0 226 nr_hardirq_read_unsafe++;
ian@0 227
ian@0 228 sum_forward_deps += count_forward_deps(class);
ian@0 229 }
ian@0 230 #ifdef CONFIG_LOCKDEP_DEBUG
ian@0 231 DEBUG_LOCKS_WARN_ON(debug_atomic_read(&nr_unused_locks) != nr_unused);
ian@0 232 #endif
ian@0 233 seq_printf(m, " lock-classes: %11lu [max: %lu]\n",
ian@0 234 nr_lock_classes, MAX_LOCKDEP_KEYS);
ian@0 235 seq_printf(m, " direct dependencies: %11lu [max: %lu]\n",
ian@0 236 nr_list_entries, MAX_LOCKDEP_ENTRIES);
ian@0 237 seq_printf(m, " indirect dependencies: %11lu\n",
ian@0 238 sum_forward_deps);
ian@0 239
ian@0 240 /*
ian@0 241 * Total number of dependencies:
ian@0 242 *
ian@0 243 * All irq-safe locks may nest inside irq-unsafe locks,
ian@0 244 * plus all the other known dependencies:
ian@0 245 */
ian@0 246 seq_printf(m, " all direct dependencies: %11lu\n",
ian@0 247 nr_irq_unsafe * nr_irq_safe +
ian@0 248 nr_hardirq_unsafe * nr_hardirq_safe +
ian@0 249 nr_list_entries);
ian@0 250
ian@0 251 /*
ian@0 252 * Estimated factor between direct and indirect
ian@0 253 * dependencies:
ian@0 254 */
ian@0 255 if (nr_list_entries)
ian@0 256 factor = sum_forward_deps / nr_list_entries;
ian@0 257
ian@0 258 seq_printf(m, " dependency chains: %11lu [max: %lu]\n",
ian@0 259 nr_lock_chains, MAX_LOCKDEP_CHAINS);
ian@0 260
ian@0 261 #ifdef CONFIG_TRACE_IRQFLAGS
ian@0 262 seq_printf(m, " in-hardirq chains: %11u\n",
ian@0 263 nr_hardirq_chains);
ian@0 264 seq_printf(m, " in-softirq chains: %11u\n",
ian@0 265 nr_softirq_chains);
ian@0 266 #endif
ian@0 267 seq_printf(m, " in-process chains: %11u\n",
ian@0 268 nr_process_chains);
ian@0 269 seq_printf(m, " stack-trace entries: %11lu [max: %lu]\n",
ian@0 270 nr_stack_trace_entries, MAX_STACK_TRACE_ENTRIES);
ian@0 271 seq_printf(m, " combined max dependencies: %11u\n",
ian@0 272 (nr_hardirq_chains + 1) *
ian@0 273 (nr_softirq_chains + 1) *
ian@0 274 (nr_process_chains + 1)
ian@0 275 );
ian@0 276 seq_printf(m, " hardirq-safe locks: %11lu\n",
ian@0 277 nr_hardirq_safe);
ian@0 278 seq_printf(m, " hardirq-unsafe locks: %11lu\n",
ian@0 279 nr_hardirq_unsafe);
ian@0 280 seq_printf(m, " softirq-safe locks: %11lu\n",
ian@0 281 nr_softirq_safe);
ian@0 282 seq_printf(m, " softirq-unsafe locks: %11lu\n",
ian@0 283 nr_softirq_unsafe);
ian@0 284 seq_printf(m, " irq-safe locks: %11lu\n",
ian@0 285 nr_irq_safe);
ian@0 286 seq_printf(m, " irq-unsafe locks: %11lu\n",
ian@0 287 nr_irq_unsafe);
ian@0 288
ian@0 289 seq_printf(m, " hardirq-read-safe locks: %11lu\n",
ian@0 290 nr_hardirq_read_safe);
ian@0 291 seq_printf(m, " hardirq-read-unsafe locks: %11lu\n",
ian@0 292 nr_hardirq_read_unsafe);
ian@0 293 seq_printf(m, " softirq-read-safe locks: %11lu\n",
ian@0 294 nr_softirq_read_safe);
ian@0 295 seq_printf(m, " softirq-read-unsafe locks: %11lu\n",
ian@0 296 nr_softirq_read_unsafe);
ian@0 297 seq_printf(m, " irq-read-safe locks: %11lu\n",
ian@0 298 nr_irq_read_safe);
ian@0 299 seq_printf(m, " irq-read-unsafe locks: %11lu\n",
ian@0 300 nr_irq_read_unsafe);
ian@0 301
ian@0 302 seq_printf(m, " uncategorized locks: %11lu\n",
ian@0 303 nr_uncategorized);
ian@0 304 seq_printf(m, " unused locks: %11lu\n",
ian@0 305 nr_unused);
ian@0 306 seq_printf(m, " max locking depth: %11u\n",
ian@0 307 max_lockdep_depth);
ian@0 308 seq_printf(m, " max recursion depth: %11u\n",
ian@0 309 max_recursion_depth);
ian@0 310 lockdep_stats_debug_show(m);
ian@0 311 seq_printf(m, " debug_locks: %11u\n",
ian@0 312 debug_locks);
ian@0 313
ian@0 314 return 0;
ian@0 315 }
ian@0 316
ian@0 317 static int lockdep_stats_open(struct inode *inode, struct file *file)
ian@0 318 {
ian@0 319 return single_open(file, lockdep_stats_show, NULL);
ian@0 320 }
ian@0 321
ian@0 322 static struct file_operations proc_lockdep_stats_operations = {
ian@0 323 .open = lockdep_stats_open,
ian@0 324 .read = seq_read,
ian@0 325 .llseek = seq_lseek,
ian@0 326 .release = seq_release,
ian@0 327 };
ian@0 328
ian@0 329 static int __init lockdep_proc_init(void)
ian@0 330 {
ian@0 331 struct proc_dir_entry *entry;
ian@0 332
ian@0 333 entry = create_proc_entry("lockdep", S_IRUSR, NULL);
ian@0 334 if (entry)
ian@0 335 entry->proc_fops = &proc_lockdep_operations;
ian@0 336
ian@0 337 entry = create_proc_entry("lockdep_stats", S_IRUSR, NULL);
ian@0 338 if (entry)
ian@0 339 entry->proc_fops = &proc_lockdep_stats_operations;
ian@0 340
ian@0 341 return 0;
ian@0 342 }
ian@0 343
ian@0 344 __initcall(lockdep_proc_init);
ian@0 345