aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/lockdep-design.txt30
-rw-r--r--kernel/lockdep.c24
-rw-r--r--kernel/lockdep_internals.h7
-rw-r--r--kernel/lockdep_proc.c6
4 files changed, 36 insertions, 31 deletions
diff --git a/Documentation/lockdep-design.txt b/Documentation/lockdep-design.txt
index 488773018152..938ea22f2cc0 100644
--- a/Documentation/lockdep-design.txt
+++ b/Documentation/lockdep-design.txt
@@ -27,33 +27,37 @@ lock-class.
27State 27State
28----- 28-----
29 29
30The validator tracks lock-class usage history into 5 separate state bits: 30The validator tracks lock-class usage history into 4n + 1 separate state bits:
31 31
32- 'ever held in hardirq context' [ == hardirq-safe ] 32- 'ever held in STATE context'
33- 'ever held in softirq context' [ == softirq-safe ] 33- 'ever head as readlock in STATE context'
34- 'ever held with hardirqs enabled' [ == hardirq-unsafe ] 34- 'ever head with STATE enabled'
35- 'ever held with softirqs and hardirqs enabled' [ == softirq-unsafe ] 35- 'ever head as readlock with STATE enabled'
36
37Where STATE can be either one of (kernel/lockdep_states.h)
38 - hardirq
39 - softirq
40 - reclaim_fs
36 41
37- 'ever used' [ == !unused ] 42- 'ever used' [ == !unused ]
38 43
39When locking rules are violated, these 4 state bits are presented in the 44When locking rules are violated, these state bits are presented in the
40locking error messages, inside curlies. A contrived example: 45locking error messages, inside curlies. A contrived example:
41 46
42 modprobe/2287 is trying to acquire lock: 47 modprobe/2287 is trying to acquire lock:
43 (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24 48 (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
44 49
45 but task is already holding lock: 50 but task is already holding lock:
46 (&sio_locks[i].lock){--..}, at: [<c02867fd>] mutex_lock+0x21/0x24 51 (&sio_locks[i].lock){-.-...}, at: [<c02867fd>] mutex_lock+0x21/0x24
47 52
48 53
49The bit position indicates hardirq, softirq, hardirq-read, 54The bit position indicates STATE, STATE-read, for each of the states listed
50softirq-read respectively, and the character displayed in each 55above, and the character displayed in each indicates:
51indicates:
52 56
53 '.' acquired while irqs disabled 57 '.' acquired while irqs disabled
54 '+' acquired in irq context 58 '+' acquired in irq context
55 '-' acquired with irqs enabled 59 '-' acquired with irqs enabled
56 '?' read acquired in irq context with irqs enabled. 60 '?' acquired in irq context with irqs enabled.
57 61
58Unused mutexes cannot be part of the cause of an error. 62Unused mutexes cannot be part of the cause of an error.
59 63
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 1b4ee3c0b789..22ced8d4912f 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -487,25 +487,25 @@ static char get_usage_char(struct lock_class *class, enum lock_usage_bit bit)
487 return c; 487 return c;
488} 488}
489 489
490void 490void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS])
491get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
492 char *c4, char *c5, char *c6)
493{ 491{
494 *c1 = get_usage_char(class, LOCK_USED_IN_HARDIRQ); 492 int i = 0;
495 *c2 = get_usage_char(class, LOCK_USED_IN_SOFTITQ);
496 *c3 = get_usage_char(class, LOCK_USED_IN_HARDIRQ_READ);
497 *c4 = get_usage_char(class, LOCK_USED_IN_SOFTITQ_READ);
498 493
499 *c5 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS); 494#define LOCKDEP_STATE(__STATE) \
500 *c6 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS_READ); 495 usage[i++] = get_usage_char(class, LOCK_USED_IN_##__STATE); \
496 usage[i++] = get_usage_char(class, LOCK_USED_IN_##__STATE##_READ);
497#include "lockdep_states.h"
498#undef LOCKDEP_STATE
499
500 usage[i] = '\0';
501} 501}
502 502
503static void print_lock_name(struct lock_class *class) 503static void print_lock_name(struct lock_class *class)
504{ 504{
505 char str[KSYM_NAME_LEN], c1, c2, c3, c4, c5, c6; 505 char str[KSYM_NAME_LEN], usage[LOCK_USAGE_CHARS];
506 const char *name; 506 const char *name;
507 507
508 get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6); 508 get_usage_chars(class, usage);
509 509
510 name = class->name; 510 name = class->name;
511 if (!name) { 511 if (!name) {
@@ -518,7 +518,7 @@ static void print_lock_name(struct lock_class *class)
518 if (class->subclass) 518 if (class->subclass)
519 printk("/%d", class->subclass); 519 printk("/%d", class->subclass);
520 } 520 }
521 printk("){%c%c%c%c%c%c}", c1, c2, c3, c4, c5, c6); 521 printk("){%s}", usage);
522} 522}
523 523
524static void print_lockdep_cache(struct lockdep_map *lock) 524static void print_lockdep_cache(struct lockdep_map *lock)
diff --git a/kernel/lockdep_internals.h b/kernel/lockdep_internals.h
index 7e653e66ce5a..a2cc7e9a6e84 100644
--- a/kernel/lockdep_internals.h
+++ b/kernel/lockdep_internals.h
@@ -70,9 +70,10 @@ enum {
70extern struct list_head all_lock_classes; 70extern struct list_head all_lock_classes;
71extern struct lock_chain lock_chains[]; 71extern struct lock_chain lock_chains[];
72 72
73extern void 73#define LOCK_USAGE_CHARS (1+LOCK_USAGE_STATES/2)
74get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, 74
75 char *c4, char *c5, char *c6); 75extern void get_usage_chars(struct lock_class *class,
76 char usage[LOCK_USAGE_CHARS]);
76 77
77extern const char * __get_key_name(struct lockdep_subclass_key *key, char *str); 78extern const char * __get_key_name(struct lockdep_subclass_key *key, char *str);
78 79
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index bd474fd9df9d..b51064ce564a 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -84,7 +84,7 @@ static int l_show(struct seq_file *m, void *v)
84{ 84{
85 struct lock_class *class = v; 85 struct lock_class *class = v;
86 struct lock_list *entry; 86 struct lock_list *entry;
87 char c1, c2, c3, c4, c5, c6; 87 char usage[LOCK_USAGE_CHARS];
88 88
89 if (v == SEQ_START_TOKEN) { 89 if (v == SEQ_START_TOKEN) {
90 seq_printf(m, "all lock classes:\n"); 90 seq_printf(m, "all lock classes:\n");
@@ -100,8 +100,8 @@ static int l_show(struct seq_file *m, void *v)
100 seq_printf(m, " BD:%5ld", lockdep_count_backward_deps(class)); 100 seq_printf(m, " BD:%5ld", lockdep_count_backward_deps(class));
101#endif 101#endif
102 102
103 get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6); 103 get_usage_chars(class, usage);
104 seq_printf(m, " %c%c%c%c%c%c", c1, c2, c3, c4, c5, c6); 104 seq_printf(m, " %s", usage);
105 105
106 seq_printf(m, ": "); 106 seq_printf(m, ": ");
107 print_name(m, class); 107 print_name(m, class);