ARM: 8049/1: ftrace/add save_stack_trace_regs() implementation
authorLin Yongting <linyongting@gmail.com>
Sun, 4 May 2014 15:27:41 +0000 (16:27 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 30 May 2014 00:12:32 +0000 (01:12 +0100)
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>
arch/arm/kernel/stacktrace.c

index 5a80ddfe7031aea97ae5c347a20ceccb80ae97fa..f065eb05d254ab89fadf1fcde45ce82e99fda0e8 100644 (file)
@@ -149,6 +149,25 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
                trace->entries[trace->nr_entries++] = ULONG_MAX;
 }
 
+void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
+{
+       struct stack_trace_data data;
+       struct stackframe frame;
+
+       data.trace = trace;
+       data.skip = trace->skip;
+       data.no_sched_functions = 0;
+
+       frame.fp = regs->ARM_fp;
+       frame.sp = regs->ARM_sp;
+       frame.lr = regs->ARM_lr;
+       frame.pc = regs->ARM_pc;
+
+       walk_stackframe(&frame, save_trace, &data);
+       if (trace->nr_entries < trace->max_entries)
+               trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+
 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
        __save_stack_trace(tsk, trace, 1);
This page took 0.035627 seconds and 5 git commands to generate.