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>
This commit is contained in:
Peter Zijlstra 2009-01-22 17:53:47 +01:00 committed by Ingo Molnar
parent 3ff176ca47
commit f510b233cf
4 changed files with 36 additions and 31 deletions

View File

@ -27,33 +27,37 @@ lock-class.
State 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 STATE context'
- 'ever held in softirq context' [ == softirq-safe ] - 'ever head as readlock in STATE context'
- 'ever held with hardirqs enabled' [ == hardirq-unsafe ] - 'ever head with STATE enabled'
- 'ever held with softirqs and hardirqs enabled' [ == softirq-unsafe ] - '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 ] - 'ever used' [ == !unused ]
When locking rules are violated, these 4 state bits are presented in the When locking rules are violated, these state bits are presented in the
locking error messages, inside curlies. A contrived example: locking error messages, inside curlies. A contrived example:
modprobe/2287 is trying to acquire lock: 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: 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, The bit position indicates STATE, STATE-read, for each of the states listed
softirq-read respectively, and the character displayed in each above, and the character displayed in each indicates:
indicates:
'.' acquired while irqs disabled '.' acquired while irqs disabled
'+' acquired in irq context '+' acquired in irq context
'-' acquired with irqs enabled '-' 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. Unused mutexes cannot be part of the cause of an error.

View File

@ -487,25 +487,25 @@ static char get_usage_char(struct lock_class *class, enum lock_usage_bit bit)
return c; return c;
} }
void void get_usage_chars(struct lock_class *class, char usage[LOCK_USAGE_CHARS])
get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
char *c4, char *c5, char *c6)
{ {
*c1 = get_usage_char(class, LOCK_USED_IN_HARDIRQ); int i = 0;
*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);
*c5 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS); #define LOCKDEP_STATE(__STATE) \
*c6 = get_usage_char(class, LOCK_USED_IN_RECLAIM_FS_READ); 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) 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; const char *name;
get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6); get_usage_chars(class, usage);
name = class->name; name = class->name;
if (!name) { if (!name) {
@ -518,7 +518,7 @@ static void print_lock_name(struct lock_class *class)
if (class->subclass) if (class->subclass)
printk("/%d", 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) static void print_lockdep_cache(struct lockdep_map *lock)

View File

@ -70,9 +70,10 @@ enum {
extern struct list_head all_lock_classes; extern struct list_head all_lock_classes;
extern struct lock_chain lock_chains[]; extern struct lock_chain lock_chains[];
extern void #define LOCK_USAGE_CHARS (1+LOCK_USAGE_STATES/2)
get_usage_chars(struct lock_class *class, char *c1, char *c2, char *c3,
char *c4, char *c5, char *c6); 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); extern const char * __get_key_name(struct lockdep_subclass_key *key, char *str);

View File

@ -84,7 +84,7 @@ static int l_show(struct seq_file *m, void *v)
{ {
struct lock_class *class = v; struct lock_class *class = v;
struct lock_list *entry; struct lock_list *entry;
char c1, c2, c3, c4, c5, c6; char usage[LOCK_USAGE_CHARS];
if (v == SEQ_START_TOKEN) { if (v == SEQ_START_TOKEN) {
seq_printf(m, "all lock classes:\n"); 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)); seq_printf(m, " BD:%5ld", lockdep_count_backward_deps(class));
#endif #endif
get_usage_chars(class, &c1, &c2, &c3, &c4, &c5, &c6); get_usage_chars(class, usage);
seq_printf(m, " %c%c%c%c%c%c", c1, c2, c3, c4, c5, c6); seq_printf(m, " %s", usage);
seq_printf(m, ": "); seq_printf(m, ": ");
print_name(m, class); print_name(m, class);