aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/stacktrace.c
diff options
context:
space:
mode:
authorLin Yongting <linyongting@gmail.com>2014-05-04 11:27:41 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-05-29 20:12:32 -0400
commit9c986661638c69772f5479c4715061239ec61b29 (patch)
tree01d88c6ddbef930c205f0549203dbc9a6efecb00 /arch/arm/kernel/stacktrace.c
parent2961b4bf70f833f16d522823ac16c5bb9e277ef7 (diff)
ARM: 8049/1: ftrace/add save_stack_trace_regs() implementation
When configure kprobe events of ftrace with "stacktrace" option enabled in arm, there is no stacktrace was recorded after the kprobe event was triggered. The root cause is no save_stack_trace_regs() function implemented. Implement the save_stack_trace_regs() function in arm, then ftrace will call this architecture-related function to record the stacktrace into ring buffer. After this fix, stacktrace can be recorded, for example: # mount -t debugfs nodev /sys/kernel/debug # echo "p:netrx net_rx_action" >> /sys/kernel/debug/tracing/kprobe_events # echo 1 > /sys/kernel/debug/tracing/events/kprobes/netrx/enable # echo 1 > /sys/kernel/debug/tracing/options/stacktrace # echo 1 > /sys/kernel/debug/tracing/tracing_on # ping 127.0.0.1 -c 1 # echo 0 > /sys/kernel/debug/tracing/tracing_on # cat /sys/kernel/debug/tracing/trace # tracer: nop # # entries-in-buffer/entries-written: 12/12 #P:1 # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | <------ missing some entries ----------------> ping-1200 [000] dNs1 667.603250: netrx: (net_rx_action+0x0/0x1f8) ping-1200 [000] dNs1 667.604738: <stack trace> => net_rx_action => do_softirq => local_bh_enable => ip_finish_output => ip_output => ip_local_out => ip_send_skb => ip_push_pending_frames => raw_sendmsg => inet_sendmsg => sock_sendmsg => SyS_sendto => ret_fast_syscall Signed-off-by: Lin Yongting <linyongting@gmail.com> Acked-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/stacktrace.c')
-rw-r--r--arch/arm/kernel/stacktrace.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index 5a80ddfe7031..f065eb05d254 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -149,6 +149,25 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
149 trace->entries[trace->nr_entries++] = ULONG_MAX; 149 trace->entries[trace->nr_entries++] = ULONG_MAX;
150} 150}
151 151
152void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
153{
154 struct stack_trace_data data;
155 struct stackframe frame;
156
157 data.trace = trace;
158 data.skip = trace->skip;
159 data.no_sched_functions = 0;
160
161 frame.fp = regs->ARM_fp;
162 frame.sp = regs->ARM_sp;
163 frame.lr = regs->ARM_lr;
164 frame.pc = regs->ARM_pc;
165
166 walk_stackframe(&frame, save_trace, &data);
167 if (trace->nr_entries < trace->max_entries)
168 trace->entries[trace->nr_entries++] = ULONG_MAX;
169}
170
152void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 171void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
153{ 172{
154 __save_stack_trace(tsk, trace, 1); 173 __save_stack_trace(tsk, trace, 1);