aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/stacktrace.c
diff options
context:
space:
mode:
authorMatt Fleming <matt@console-pimps.org>2009-08-07 11:11:19 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-08-12 22:50:08 -0400
commit4e14dfc722b8e9e07a355f97aa60a3d9f0739071 (patch)
tree0d5b9f6ecb99a050e2ddb839aead6a1d235c26cb /arch/sh/kernel/stacktrace.c
parent922b0dc59bb43f7ff3bb8b9558ffeb3ad6af528e (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.c87
1 files changed, 61 insertions, 26 deletions
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
index 1a2a5eb76e4..6c24a400b05 100644
--- a/arch/sh/kernel/stacktrace.c
+++ b/arch/sh/kernel/stacktrace.c
@@ -14,46 +14,81 @@
14#include <linux/thread_info.h> 14#include <linux/thread_info.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <asm/ptrace.h> 16#include <asm/ptrace.h>
17#include <asm/stacktrace.h>
18
19static void save_stack_warning(void *data, char *msg)
20{
21}
22
23static void
24save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
25{
26}
27
28static int save_stack_stack(void *data, char *name)
29{
30 return 0;
31}
17 32
18/* 33/*
19 * Save stack-backtrace addresses into a stack_trace buffer. 34 * Save stack-backtrace addresses into a stack_trace buffer.
20 */ 35 */
36static void save_stack_address(void *data, unsigned long addr, int reliable)
37{
38 struct stack_trace *trace = data;
39
40 if (trace->skip > 0) {
41 trace->skip--;
42 return;
43 }
44
45 if (trace->nr_entries < trace->max_entries)
46 trace->entries[trace->nr_entries++] = addr;
47}
48
49static const struct stacktrace_ops save_stack_ops = {
50 .warning = save_stack_warning,
51 .warning_symbol = save_stack_warning_symbol,
52 .stack = save_stack_stack,
53 .address = save_stack_address,
54};
55
21void save_stack_trace(struct stack_trace *trace) 56void save_stack_trace(struct stack_trace *trace)
22{ 57{
23 unsigned long *sp = (unsigned long *)current_stack_pointer; 58 unsigned long *sp = (unsigned long *)current_stack_pointer;
24 59
25 while (!kstack_end(sp)) { 60 dump_trace(current, NULL, sp, &save_stack_ops, trace);
26 unsigned long addr = *sp++;
27
28 if (__kernel_text_address(addr)) {
29 if (trace->skip > 0)
30 trace->skip--;
31 else
32 trace->entries[trace->nr_entries++] = addr;
33 if (trace->nr_entries >= trace->max_entries)
34 break;
35 }
36 }
37} 61}
38EXPORT_SYMBOL_GPL(save_stack_trace); 62EXPORT_SYMBOL_GPL(save_stack_trace);
39 63
64static void
65save_stack_address_nosched(void *data, unsigned long addr, int reliable)
66{
67 struct stack_trace *trace = (struct stack_trace *)data;
68
69 if (in_sched_functions(addr))
70 return;
71
72 if (trace->skip > 0) {
73 trace->skip--;
74 return;
75 }
76
77 if (trace->nr_entries < trace->max_entries)
78 trace->entries[trace->nr_entries++] = addr;
79}
80
81static const struct stacktrace_ops save_stack_ops_nosched = {
82 .warning = save_stack_warning,
83 .warning_symbol = save_stack_warning_symbol,
84 .stack = save_stack_stack,
85 .address = save_stack_address_nosched,
86};
87
40void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 88void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
41{ 89{
42 unsigned long *sp = (unsigned long *)tsk->thread.sp; 90 unsigned long *sp = (unsigned long *)tsk->thread.sp;
43 91
44 while (!kstack_end(sp)) { 92 dump_trace(current, NULL, sp, &save_stack_ops_nosched, trace);
45 unsigned long addr = *sp++;
46
47 if (__kernel_text_address(addr)) {
48 if (in_sched_functions(addr))
49 break;
50 if (trace->skip > 0)
51 trace->skip--;
52 else
53 trace->entries[trace->nr_entries++] = addr;
54 if (trace->nr_entries >= trace->max_entries)
55 break;
56 }
57 }
58} 93}
59EXPORT_SYMBOL_GPL(save_stack_trace_tsk); 94EXPORT_SYMBOL_GPL(save_stack_trace_tsk);