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:
parent
3ff176ca47
commit
f510b233cf
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue