Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=068135e63518314d4efd711142f674ad0841599e
Commit:     068135e63518314d4efd711142f674ad0841599e
Parent:     381a229209aa6f7f72375797b7bcfcfe2ae6fcbb
Author:     Jason Baron <[EMAIL PROTECTED]>
AuthorDate: Sat Feb 10 01:44:59 2007 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Sun Feb 11 10:51:26 2007 -0800

    [PATCH] lockdep: add graph depth information to /proc/lockdep
    
    Generate locking graph information into /proc/lockdep, for lock hierarchy
    documentation and visualization purposes.
    
    sample output:
    
     c089fd5c OPS:     138 FD:   14 BD:    1 --..: &tty->termios_mutex
      -> [c07a3430] tty_ldisc_lock
      -> [c07a37f0] &port_lock_key
      -> [c07afdc0] &rq->rq_lock_key#2
    
    The lock classes listed are all the first-hop lock dependencies that
    lockdep has seen so far.
    
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 include/linux/lockdep.h |    1 +
 kernel/lockdep.c        |   19 ++++++++++++-------
 kernel/lockdep_proc.c   |   41 +++++++++++++++++++++++++++++------------
 3 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index ea097dd..7e1160d 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -132,6 +132,7 @@ struct lock_list {
        struct list_head                entry;
        struct lock_class               *class;
        struct stack_trace              trace;
+       int                             distance;
 };
 
 /*
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 2d616f4..592c576 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -490,7 +490,7 @@ static void print_lock_dependencies(struct lock_class 
*class, int depth)
  * Add a new dependency to the head of the list:
  */
 static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
-                           struct list_head *head, unsigned long ip)
+                           struct list_head *head, unsigned long ip, int 
distance)
 {
        struct lock_list *entry;
        /*
@@ -502,6 +502,7 @@ static int add_lock_to_list(struct lock_class *class, 
struct lock_class *this,
                return 0;
 
        entry->class = this;
+       entry->distance = distance;
        if (!save_trace(&entry->trace))
                return 0;
 
@@ -906,7 +907,7 @@ check_deadlock(struct task_struct *curr, struct held_lock 
*next,
  */
 static int
 check_prev_add(struct task_struct *curr, struct held_lock *prev,
-              struct held_lock *next)
+              struct held_lock *next, int distance)
 {
        struct lock_list *entry;
        int ret;
@@ -984,8 +985,11 @@ check_prev_add(struct task_struct *curr, struct held_lock 
*prev,
         *  L2 added to its dependency list, due to the first chain.)
         */
        list_for_each_entry(entry, &prev->class->locks_after, entry) {
-               if (entry->class == next->class)
+               if (entry->class == next->class) {
+                       if (distance == 1)
+                               entry->distance = 1;
                        return 2;
+               }
        }
 
        /*
@@ -993,12 +997,13 @@ check_prev_add(struct task_struct *curr, struct held_lock 
*prev,
         * to the previous lock's dependency list:
         */
        ret = add_lock_to_list(prev->class, next->class,
-                              &prev->class->locks_after, next->acquire_ip);
+                              &prev->class->locks_after, next->acquire_ip, 
distance);
+
        if (!ret)
                return 0;
 
        ret = add_lock_to_list(next->class, prev->class,
-                              &next->class->locks_before, next->acquire_ip);
+                              &next->class->locks_before, next->acquire_ip, 
distance);
        if (!ret)
                return 0;
 
@@ -1046,13 +1051,14 @@ check_prevs_add(struct task_struct *curr, struct 
held_lock *next)
                goto out_bug;
 
        for (;;) {
+               int distance = curr->lockdep_depth - depth + 1;
                hlock = curr->held_locks + depth-1;
                /*
                 * Only non-recursive-read entries get new dependencies
                 * added:
                 */
                if (hlock->read != 2) {
-                       if (!check_prev_add(curr, hlock, next))
+                       if (!check_prev_add(curr, hlock, next, distance))
                                return 0;
                        /*
                         * Stop after the first non-trylock entry,
@@ -2779,4 +2785,3 @@ void debug_show_held_locks(struct task_struct *task)
 }
 
 EXPORT_SYMBOL_GPL(debug_show_held_locks);
-
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index b554b40..57a547a 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -77,12 +77,29 @@ static unsigned long count_backward_deps(struct lock_class 
*class)
        return ret;
 }
 
+static void print_name(struct seq_file *m, struct lock_class *class)
+{
+       char str[128];
+       const char *name = class->name;
+
+       if (!name) {
+               name = __get_key_name(class->key, str);
+               seq_printf(m, "%s", name);
+       } else{
+               seq_printf(m, "%s", name);
+               if (class->name_version > 1)
+                       seq_printf(m, "#%d", class->name_version);
+               if (class->subclass)
+                       seq_printf(m, "/%d", class->subclass);
+       }
+}
+
 static int l_show(struct seq_file *m, void *v)
 {
        unsigned long nr_forward_deps, nr_backward_deps;
        struct lock_class *class = m->private;
-       char str[128], c1, c2, c3, c4;
-       const char *name;
+       struct lock_list *entry;
+       char c1, c2, c3, c4;
 
        seq_printf(m, "%p", class->key);
 #ifdef CONFIG_DEBUG_LOCKDEP
@@ -97,16 +114,16 @@ static int l_show(struct seq_file *m, void *v)
        get_usage_chars(class, &c1, &c2, &c3, &c4);
        seq_printf(m, " %c%c%c%c", c1, c2, c3, c4);
 
-       name = class->name;
-       if (!name) {
-               name = __get_key_name(class->key, str);
-               seq_printf(m, ": %s", name);
-       } else{
-               seq_printf(m, ": %s", name);
-               if (class->name_version > 1)
-                       seq_printf(m, "#%d", class->name_version);
-               if (class->subclass)
-                       seq_printf(m, "/%d", class->subclass);
+       seq_printf(m, ": ");
+       print_name(m, class);
+       seq_puts(m, "\n");
+
+       list_for_each_entry(entry, &class->locks_after, entry) {
+               if (entry->distance == 1) {
+                       seq_printf(m, " -> [%p] ", entry->class);
+                       print_name(m, entry->class);
+                       seq_puts(m, "\n");
+               }
        }
        seq_puts(m, "\n");
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to