diff options
| author | Matt Fleming <matt@console-pimps.org> | 2009-08-07 16:11:19 +0100 | 
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2009-08-13 11:50:08 +0900 | 
| commit | 4e14dfc722b8e9e07a355f97aa60a3d9f0739071 (patch) | |
| tree | 0d5b9f6ecb99a050e2ddb839aead6a1d235c26cb /arch/sh/kernel/stacktrace.c | |
| parent | 922b0dc59bb43f7ff3bb8b9558ffeb3ad6af528e (diff) | |
sh: Use the generalized stacktrace ops
Copy the stacktrace ops code from x86 and provide a central function for
use by functions that need to dump a callstack.
Signed-off-by: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/stacktrace.c')
| -rw-r--r-- | arch/sh/kernel/stacktrace.c | 87 | 
1 files changed, 61 insertions, 26 deletions
| diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c index 1a2a5eb76e41..6c24a400b05e 100644 --- a/arch/sh/kernel/stacktrace.c +++ b/arch/sh/kernel/stacktrace.c @@ -14,46 +14,81 @@  #include <linux/thread_info.h>  #include <linux/module.h>  #include <asm/ptrace.h> +#include <asm/stacktrace.h> + +static void save_stack_warning(void *data, char *msg) +{ +} + +static void +save_stack_warning_symbol(void *data, char *msg, unsigned long symbol) +{ +} + +static int save_stack_stack(void *data, char *name) +{ +	return 0; +}  /*   * Save stack-backtrace addresses into a stack_trace buffer.   */ +static void save_stack_address(void *data, unsigned long addr, int reliable) +{ +	struct stack_trace *trace = data; + +	if (trace->skip > 0) { +		trace->skip--; +		return; +	} + +	if (trace->nr_entries < trace->max_entries) +		trace->entries[trace->nr_entries++] = addr; +} + +static const struct stacktrace_ops save_stack_ops = { +	.warning = save_stack_warning, +	.warning_symbol = save_stack_warning_symbol, +	.stack = save_stack_stack, +	.address = save_stack_address, +}; +  void save_stack_trace(struct stack_trace *trace)  {  	unsigned long *sp = (unsigned long *)current_stack_pointer; -	while (!kstack_end(sp)) { -		unsigned long addr = *sp++; - -		if (__kernel_text_address(addr)) { -			if (trace->skip > 0) -				trace->skip--; -			else -				trace->entries[trace->nr_entries++] = addr; -			if (trace->nr_entries >= trace->max_entries) -				break; -		} -	} +	dump_trace(current, NULL, sp,  &save_stack_ops, trace);  }  EXPORT_SYMBOL_GPL(save_stack_trace); +static void +save_stack_address_nosched(void *data, unsigned long addr, int reliable) +{ +	struct stack_trace *trace = (struct stack_trace *)data; + +	if (in_sched_functions(addr)) +		return; + +	if (trace->skip > 0) { +		trace->skip--; +		return; +	} + +	if (trace->nr_entries < trace->max_entries) +		trace->entries[trace->nr_entries++] = addr; +} + +static const struct stacktrace_ops save_stack_ops_nosched = { +	.warning = save_stack_warning, +	.warning_symbol = save_stack_warning_symbol, +	.stack = save_stack_stack, +	.address = save_stack_address_nosched, +}; +  void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)  {  	unsigned long *sp = (unsigned long *)tsk->thread.sp; -	while (!kstack_end(sp)) { -		unsigned long addr = *sp++; - -		if (__kernel_text_address(addr)) { -			if (in_sched_functions(addr)) -				break; -			if (trace->skip > 0) -				trace->skip--; -			else -				trace->entries[trace->nr_entries++] = addr; -			if (trace->nr_entries >= trace->max_entries) -				break; -		} -	} +	dump_trace(current, NULL, sp,  &save_stack_ops_nosched, trace);  }  EXPORT_SYMBOL_GPL(save_stack_trace_tsk); | 
