diff options
Diffstat (limited to 'arch/sparc/kernel/stacktrace.c')
-rw-r--r-- | arch/sparc/kernel/stacktrace.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/arch/sparc/kernel/stacktrace.c b/arch/sparc/kernel/stacktrace.c index acb12f673757..3e0815349630 100644 --- a/arch/sparc/kernel/stacktrace.c +++ b/arch/sparc/kernel/stacktrace.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/sched.h> | 1 | #include <linux/sched.h> |
2 | #include <linux/stacktrace.h> | 2 | #include <linux/stacktrace.h> |
3 | #include <linux/thread_info.h> | 3 | #include <linux/thread_info.h> |
4 | #include <linux/ftrace.h> | ||
4 | #include <linux/module.h> | 5 | #include <linux/module.h> |
5 | #include <asm/ptrace.h> | 6 | #include <asm/ptrace.h> |
6 | #include <asm/stacktrace.h> | 7 | #include <asm/stacktrace.h> |
@@ -12,6 +13,10 @@ static void __save_stack_trace(struct thread_info *tp, | |||
12 | bool skip_sched) | 13 | bool skip_sched) |
13 | { | 14 | { |
14 | unsigned long ksp, fp; | 15 | unsigned long ksp, fp; |
16 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
17 | struct task_struct *t; | ||
18 | int graph = 0; | ||
19 | #endif | ||
15 | 20 | ||
16 | if (tp == current_thread_info()) { | 21 | if (tp == current_thread_info()) { |
17 | stack_trace_flush(); | 22 | stack_trace_flush(); |
@@ -21,6 +26,9 @@ static void __save_stack_trace(struct thread_info *tp, | |||
21 | } | 26 | } |
22 | 27 | ||
23 | fp = ksp + STACK_BIAS; | 28 | fp = ksp + STACK_BIAS; |
29 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
30 | t = tp->task; | ||
31 | #endif | ||
24 | do { | 32 | do { |
25 | struct sparc_stackf *sf; | 33 | struct sparc_stackf *sf; |
26 | struct pt_regs *regs; | 34 | struct pt_regs *regs; |
@@ -44,8 +52,21 @@ static void __save_stack_trace(struct thread_info *tp, | |||
44 | 52 | ||
45 | if (trace->skip > 0) | 53 | if (trace->skip > 0) |
46 | trace->skip--; | 54 | trace->skip--; |
47 | else if (!skip_sched || !in_sched_functions(pc)) | 55 | else if (!skip_sched || !in_sched_functions(pc)) { |
48 | trace->entries[trace->nr_entries++] = pc; | 56 | trace->entries[trace->nr_entries++] = pc; |
57 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
58 | if ((pc + 8UL) == (unsigned long) &return_to_handler) { | ||
59 | int index = t->curr_ret_stack; | ||
60 | if (t->ret_stack && index >= graph) { | ||
61 | pc = t->ret_stack[index - graph].ret; | ||
62 | if (trace->nr_entries < | ||
63 | trace->max_entries) | ||
64 | trace->entries[trace->nr_entries++] = pc; | ||
65 | graph++; | ||
66 | } | ||
67 | } | ||
68 | #endif | ||
69 | } | ||
49 | } while (trace->nr_entries < trace->max_entries); | 70 | } while (trace->nr_entries < trace->max_entries); |
50 | } | 71 | } |
51 | 72 | ||