lockdep: get_user_chars() redo
authorPeter Zijlstra <a.p.zijlstra@chello.nl>
Thu, 22 Jan 2009 16:53:47 +0000 (17:53 +0100)
committerIngo Molnar <mingo@elte.hu>
Sat, 14 Feb 2009 22:28:22 +0000 (23:28 +0100)
Generic, states independent, get_user_chars().

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Documentation/lockdep-design.txt
kernel/lockdep.c
kernel/lockdep_internals.h
kernel/lockdep_proc.c

index 488773018152056ea159685e732e42452a7ae142..938ea22f2cc096f6838a678217e463bf9ec0cd4d 100644 (file)
@@ -27,33 +27,37 @@ lock-class.
 State
 -----
 
-The validator tracks lock-class usage history into 5 separate state bits:
+The validator tracks lock-class usage history into 4n + 1 separate state bits:
 
-- 'ever held in hardirq context'                    [ == hardirq-safe   ]
-- 'ever held in softirq context'                    [ == softirq-safe   ]
-- 'ever held with hardirqs enabled'                 [ == hardirq-unsafe ]
-- 'ever held with softirqs and hardirqs enabled'    [ == softirq-unsafe ]
+- 'ever held in STATE context'
+- 'ever head as readlock in STATE context'
+- 'ever head with STATE enabled'
+- 'ever head as readlock with STATE enabled'
+
+Where STATE can be either one of (kernel/lockdep_states.h)
+ - hardirq
+ - softirq
+ - reclaim_fs
 
 - 'ever used'                                       [ == !unused        ]
 
-When locking rules are violated, these state bits are presented in the
-locking error messages, inside curlies.  A contrived example:
+When locking rules are violated, these state bits are presented in the
+locking error messages, inside curlies. A contrived example:
 
    modprobe/2287 is trying to acquire lock:
-    (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
+    (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
 
    but task is already holding lock:
-    (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24
+    (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
 
 
-The bit position indicates hardirq, softirq, hardirq-read,
-softirq-read respectively, and the character displayed in each
-indicates:
+The bit position indicates STATE, STATE-read, for each of the states listed
+above, and the character displayed in each indicates:
 
    '.'  acquired while irqs disabled
    '+'  acquired in irq context
    '-'  acquired with irqs enabled
-   '?' read acquired in irq context with irqs enabled.
+   '?'  acquired in irq context with irqs enabled.
 
 Unused mutexes cannot be part of the cause of an error.
 
index 1b4ee3c0b7895995786e19ba80003df55b9ac01c..22ced8d4912f9f07b53dde10dcc1fcdcf34cef30 100644 (file)
@@ -487,25 +487,25 @@ static char get_usage_char(struct lock_class *class, enum lock_usage_bit bit)
        return c;
 }
 
-void
-get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
-                                       char *c4, char *c5, char *c6)
+void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS])
 {
-       *c1 = get_usage_char(class, LOCK_USED_IN_HARDIRQ);
-       *c2 = get_usage_char(class, LOCK_USED_IN_SOFTITQ);
-       *c3 = get_usage_char(class, LOCK_USED_IN_HARDIRQ_READ);
-       *c4 = get_usage_char(class, LOCK_USED_IN_SOFTITQ_READ);
+       int i = 0;
 
-       *c5 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS);
-       *c6 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS_READ);
+#define LOCKDEP_STATE(__STATE)                                                 \
+       usage[i++] = get_usage_char(class, LOCK_USED_IN_##__STATE);     \
+       usage[i++] = get_usage_char(class, LOCK_USED_IN_##__STATE##_READ);
+#include "lockdep_states.h"
+#undef LOCKDEP_STATE
+
+       usage[i] = '\0';
 }
 
 static void print_lock_name(struct lock_class *class)
 {
-       char str[KSYM_NAME_LEN], c1, c2, c3, c4, c5, c6;
+       char str[KSYM_NAME_LEN], usage[LOCK_USAGE_CHARS];
        const char *name;
 
-       get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6);
+       get_usage_chars(class, usage);
 
        name = class->name;
        if (!name) {
@@ -518,7 +518,7 @@ static void print_lock_name(struct lock_class *class)
                if (class->subclass)
                        printk("/%d", class->subclass);
        }
-       printk("){%c%c%c%c%c%c}", c1, c2, c3, c4, c5, c6);
+       printk("){%s}", usage);
 }
 
 static void print_lockdep_cache(struct lockdep_map *lock)
index 7e653e66ce5ac7bec79de89f1e65eb99bd1c6598..a2cc7e9a6e841b9e955709b9139cd96b3d803f2e 100644 (file)
@@ -70,9 +70,10 @@ enum {
 extern struct list_head all_lock_classes;
 extern struct lock_chain lock_chains[];
 
-extern void
-get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
-                                       char *c4, char *c5, char *c6);
+#define LOCK_USAGE_CHARS (1+LOCK_USAGE_STATES/2)
+
+extern void get_usage_chars(struct lock_class *class,
+                           char usage[LOCK_USAGE_CHARS]);
 
 extern const char * __get_key_name(struct lockdep_subclass_key *key, char *str);
 
index bd474fd9df9d0d525b57d99c6aacbe2fc6b1dfa0..b51064ce564aa4fa309dfeeb99f61c5dfe1acb58 100644 (file)
@@ -84,7 +84,7 @@ static int l_show(struct seq_file *m, void *v)
 {
        struct lock_class *class = v;
        struct lock_list *entry;
-       char c1, c2, c3, c4, c5, c6;
+       char usage[LOCK_USAGE_CHARS];
 
        if (v == SEQ_START_TOKEN) {
                seq_printf(m, "all lock classes:\n");
@@ -100,8 +100,8 @@ static int l_show(struct seq_file *m, void *v)
        seq_printf(m, " BD:%5ld", lockdep_count_backward_deps(class));
 #endif
 
-       get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6);
-       seq_printf(m, " %c%c%c%c%c%c", c1, c2, c3, c4, c5, c6);
+       get_usage_chars(class, usage);
+       seq_printf(m, " %s", usage);
 
        seq_printf(m, ": ");
        print_name(m, class);