diff options
| author | Huang, Ying <ying.huang@intel.com> | 2008-06-20 16:39:21 +0800 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-06-20 12:21:33 +0200 | 
| commit | 443cd507ce7f78c6f8742b72736585c031d5a921 (patch) | |
| tree | 256182911b08287661beca1f90455b14cd0b9151 /kernel/lockdep_proc.c | |
| parent | 2429e4ee78e2fa40f82a4572dd21d4f3b4de9325 (diff) | |
| download | olio-linux-3.10-443cd507ce7f78c6f8742b72736585c031d5a921.tar.xz olio-linux-3.10-443cd507ce7f78c6f8742b72736585c031d5a921.zip  | |
lockdep: add lock_class information to lock_chain and output it
This patch records array of lock_class into lock_chain, and export
lock_chain information via /proc/lockdep_chains.
It is based on x86/master branch of git-x86 tree, and has been tested
on x86_64 platform.
Signed-off-by: Huang Ying <ying.huang@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/lockdep_proc.c')
| -rw-r--r-- | kernel/lockdep_proc.c | 91 | 
1 files changed, 91 insertions, 0 deletions
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c index 688c5f1940b..14d052c8a83 100644 --- a/kernel/lockdep_proc.c +++ b/kernel/lockdep_proc.c @@ -178,6 +178,93 @@ static const struct file_operations proc_lockdep_operations = {  	.release	= seq_release,  }; +static void *lc_next(struct seq_file *m, void *v, loff_t *pos) +{ +	struct lock_chain *chain; + +	(*pos)++; + +	if (v == SEQ_START_TOKEN) +		chain = m->private; +	else { +		chain = v; + +		if (*pos < nr_lock_chains) +			chain = lock_chains + *pos; +		else +			chain = NULL; +	} + +	return chain; +} + +static void *lc_start(struct seq_file *m, loff_t *pos) +{ +	if (*pos == 0) +		return SEQ_START_TOKEN; + +	if (*pos < nr_lock_chains) +		return lock_chains + *pos; + +	return NULL; +} + +static void lc_stop(struct seq_file *m, void *v) +{ +} + +static int lc_show(struct seq_file *m, void *v) +{ +	struct lock_chain *chain = v; +	struct lock_class *class; +	int i; + +	if (v == SEQ_START_TOKEN) { +		seq_printf(m, "all lock chains:\n"); +		return 0; +	} + +	seq_printf(m, "irq_context: %d\n", chain->irq_context); + +	for (i = 0; i < chain->depth; i++) { +		class = lock_chain_get_class(chain, i); +		seq_printf(m, "[%p] ", class->key); +		print_name(m, class); +		seq_puts(m, "\n"); +	} +	seq_puts(m, "\n"); + +	return 0; +} + +static const struct seq_operations lockdep_chains_ops = { +	.start	= lc_start, +	.next	= lc_next, +	.stop	= lc_stop, +	.show	= lc_show, +}; + +static int lockdep_chains_open(struct inode *inode, struct file *file) +{ +	int res = seq_open(file, &lockdep_chains_ops); +	if (!res) { +		struct seq_file *m = file->private_data; + +		if (nr_lock_chains) +			m->private = lock_chains; +		else +			m->private = NULL; +	} +	return res; +} + +static const struct file_operations proc_lockdep_chains_operations = { +	.open		= lockdep_chains_open, +	.read		= seq_read, +	.llseek		= seq_lseek, +	.release	= seq_release, +}; +  static void lockdep_stats_debug_show(struct seq_file *m)  {  #ifdef CONFIG_DEBUG_LOCKDEP @@ -294,6 +381,8 @@ static int lockdep_stats_show(struct seq_file *m, void *v)  #ifdef CONFIG_PROVE_LOCKING  	seq_printf(m, " dependency chains:             %11lu [max: %lu]\n",  			nr_lock_chains, MAX_LOCKDEP_CHAINS); +	seq_printf(m, " dependency chain hlocks:       %11d [max: %lu]\n", +			atomic_read(&nr_chain_hlocks), MAX_LOCKDEP_CHAIN_HLOCKS);  #endif  #ifdef CONFIG_TRACE_IRQFLAGS @@ -661,6 +750,8 @@ static const struct file_operations proc_lock_stat_operations = {  static int __init lockdep_proc_init(void)  {  	proc_create("lockdep", S_IRUSR, NULL, &proc_lockdep_operations); +	proc_create("lockdep_chains", S_IRUSR, NULL, +		    &proc_lockdep_chains_operations);  	proc_create("lockdep_stats", S_IRUSR, NULL,  		    &proc_lockdep_stats_operations);  |