aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/lockdep.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-11-02 20:24:16 -0400
committerSteven Rostedt <rostedt@goodmis.org>2011-11-07 11:01:46 -0500
commite5e78d08f3ab3094783b8df08a5b6d1d1a56a58f (patch)
tree524c4faf387d4ac1dc46b23015a9d8fc4823ab88 /kernel/lockdep.c
parent3890c136357284cb0656f9dd0e62286995ad32e9 (diff)
lockdep: Show subclass in pretty print of lockdep output
The pretty print of the lockdep debug splat uses just the lock name to show how the locking scenario happens. But when it comes to nesting locks, the output becomes confusing which takes away the point of the pretty printing of the lock scenario. Without displaying the subclass info, we get the following output: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(slock-AF_INET); lock(slock-AF_INET); lock(slock-AF_INET); lock(slock-AF_INET); *** DEADLOCK *** The above looks more of a A->A locking bug than a A->B B->A. By adding the subclass to the output, we can see what really happened: other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(slock-AF_INET); lock(slock-AF_INET/1); lock(slock-AF_INET); lock(slock-AF_INET/1); *** DEADLOCK *** This bug was discovered while tracking down a real bug caught by lockdep. Link: http://lkml.kernel.org/r/20111025202049.GB25043@hostway.ca Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Reported-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Simon Kirby <sim@hostway.ca> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r--kernel/lockdep.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 91d67ce3a8d5..6bd915df5fd3 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -490,36 +490,32 @@ void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS])
490 usage[i] = '\0'; 490 usage[i] = '\0';
491} 491}
492 492
493static int __print_lock_name(struct lock_class *class) 493static void __print_lock_name(struct lock_class *class)
494{ 494{
495 char str[KSYM_NAME_LEN]; 495 char str[KSYM_NAME_LEN];
496 const char *name; 496 const char *name;
497 497
498 name = class->name; 498 name = class->name;
499 if (!name)
500 name = __get_key_name(class->key, str);
501
502 return printk("%s", name);
503}
504
505static void print_lock_name(struct lock_class *class)
506{
507 char str[KSYM_NAME_LEN], usage[LOCK_USAGE_CHARS];
508 const char *name;
509
510 get_usage_chars(class, usage);
511
512 name = class->name;
513 if (!name) { 499 if (!name) {
514 name = __get_key_name(class->key, str); 500 name = __get_key_name(class->key, str);
515 printk(" (%s", name); 501 printk("%s", name);
516 } else { 502 } else {
517 printk(" (%s", name); 503 printk("%s", name);
518 if (class->name_version > 1) 504 if (class->name_version > 1)
519 printk("#%d", class->name_version); 505 printk("#%d", class->name_version);
520 if (class->subclass) 506 if (class->subclass)
521 printk("/%d", class->subclass); 507 printk("/%d", class->subclass);
522 } 508 }
509}
510
511static void print_lock_name(struct lock_class *class)
512{
513 char usage[LOCK_USAGE_CHARS];
514
515 get_usage_chars(class, usage);
516
517 printk(" (");
518 __print_lock_name(class);
523 printk("){%s}", usage); 519 printk("){%s}", usage);
524} 520}
525 521