diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-01-22 11:53:47 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-02-14 17:28:22 -0500 |
| commit | f510b233cfc7bfd57b6007071c52aa42e3d16b06 (patch) | |
| tree | d7e91f4d82ee3bed078f5813377b73a1eb7e382f | |
| parent | 3ff176ca47911630d1555f150d36daa2d0819ea9 (diff) | |
lockdep: get_user_chars() redo
Generic, states independent, get_user_chars().
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | Documentation/lockdep-design.txt | 30 | ||||
| -rw-r--r-- | kernel/lockdep.c | 24 | ||||
| -rw-r--r-- | kernel/lockdep_internals.h | 7 | ||||
| -rw-r--r-- | kernel/lockdep_proc.c | 6 |
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. | |||
| 27 | State | 27 | State |
| 28 | ----- | 28 | ----- |
| 29 | 29 | ||
| 30 | The validator tracks lock-class usage history into 5 separate state bits: | 30 | The 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 | |||
| 37 | Where 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 | ||
| 39 | When locking rules are violated, these 4 state bits are presented in the | 44 | When locking rules are violated, these state bits are presented in the |
| 40 | locking error messages, inside curlies. A contrived example: | 45 | locking 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 | ||
| 49 | The bit position indicates hardirq, softirq, hardirq-read, | 54 | The bit position indicates STATE, STATE-read, for each of the states listed |
| 50 | softirq-read respectively, and the character displayed in each | 55 | above, and the character displayed in each indicates: |
| 51 | indicates: | ||
| 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 | ||
| 58 | Unused mutexes cannot be part of the cause of an error. | 62 | Unused 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 | ||
| 490 | void | 490 | void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS]) |
| 491 | get_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 | ||
| 503 | static void print_lock_name(struct lock_class *class) | 503 | static 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 | ||
| 524 | static void print_lockdep_cache(struct lockdep_map *lock) | 524 | static 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 { | |||
| 70 | extern struct list_head all_lock_classes; | 70 | extern struct list_head all_lock_classes; |
| 71 | extern struct lock_chain lock_chains[]; | 71 | extern struct lock_chain lock_chains[]; |
| 72 | 72 | ||
| 73 | extern void | 73 | #define LOCK_USAGE_CHARS (1+LOCK_USAGE_STATES/2) |
| 74 | get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3, | 74 | |
| 75 | char *c4, char *c5, char *c6); | 75 | extern void get_usage_chars(struct lock_class *class, |
| 76 | char usage[LOCK_USAGE_CHARS]); | ||
| 76 | 77 | ||
| 77 | extern const char * __get_key_name(struct lockdep_subclass_key *key, char *str); | 78 | extern 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); |
