Skip to content

Commit

Permalink
lockdep: Show subclass in pretty print of lockdep output
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Steven Rostedt authored and Steven Rostedt committed Nov 7, 2011
1 parent 3890c13 commit e5e78d0
Showing 1 changed file with 13 additions and 17 deletions.
30 changes: 13 additions & 17 deletions kernel/lockdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,36 +490,32 @@ void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS])
usage[i] = '\0';
}

static int __print_lock_name(struct lock_class *class)
static void __print_lock_name(struct lock_class *class)
{
char str[KSYM_NAME_LEN];
const char *name;

name = class->name;
if (!name)
name = __get_key_name(class->key, str);

return printk("%s", name);
}

static void print_lock_name(struct lock_class *class)
{
char str[KSYM_NAME_LEN], usage[LOCK_USAGE_CHARS];
const char *name;

get_usage_chars(class, usage);

name = class->name;
if (!name) {
name = __get_key_name(class->key, str);
printk(" (%s", name);
printk("%s", name);
} else {
printk(" (%s", name);
printk("%s", name);
if (class->name_version > 1)
printk("#%d", class->name_version);
if (class->subclass)
printk("/%d", class->subclass);
}
}

static void print_lock_name(struct lock_class *class)
{
char usage[LOCK_USAGE_CHARS];

get_usage_chars(class, usage);

printk(" (");
__print_lock_name(class);
printk("){%s}", usage);
}

Expand Down

0 comments on commit e5e78d0

Please sign in to comment.