Skip to content

Commit

Permalink
lockdep: get_user_chars() redo
Browse files Browse the repository at this point in the history
Generic, states independent, get_user_chars().

Signed-off-by: Peter Zijlstra <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Feb 14, 2009
1 parent 3ff176c commit f510b23
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 31 deletions.
30 changes: 17 additions & 13 deletions Documentation/lockdep-design.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 4 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.

Expand Down
24 changes: 12 additions & 12 deletions kernel/lockdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)
Expand Down
7 changes: 4 additions & 3 deletions kernel/lockdep_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
6 changes: 3 additions & 3 deletions kernel/lockdep_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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);
Expand Down

0 comments on commit f510b23

Please sign in to comment.