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:
Родитель
3ff176ca47
Коммит
f510b233cf
|
@ -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.
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче