aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/kernel/ftrace.c
diff options
context:
space:
mode:
authorTim Bird <tim.bird@am.sony.com>2010-10-09 22:24:38 +0530
committerRabin Vincent <rabin@rab.in>2010-11-19 21:43:27 +0530
commit376cfa8730c08c0394d0aa1d4a80fd8c9971f323 (patch)
treef1384eb77981241b1ab1028a50b94382c2c6e723 /arch/arm/kernel/ftrace.c
parentd3b9dc9dd2b994f396741f7086ffe7a48bacb165 (diff)
ARM: ftrace: function graph tracer support
Cc: Tim Bird <tim.bird@am.sony.com> [rabin@rab.in: rebase on top of latest code, keep code in ftrace.c instead of separate file, check for ftrace_graph_entry also] Signed-off-by: Rabin Vincent <rabin@rab.in>
Diffstat (limited to 'arch/arm/kernel/ftrace.c')
-rw-r--r--arch/arm/kernel/ftrace.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index 971ac8c36ea..7a702a50287 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -24,6 +24,7 @@
#define NOP 0xe8bd4000 /* pop {lr} */
#endif
+#ifdef CONFIG_DYNAMIC_FTRACE
#ifdef CONFIG_OLD_MCOUNT
#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
@@ -193,3 +194,36 @@ int __init ftrace_dyn_arch_init(void *data)
return 0;
}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+ unsigned long frame_pointer)
+{
+ unsigned long return_hooker = (unsigned long) &return_to_handler;
+ struct ftrace_graph_ent trace;
+ unsigned long old;
+ int err;
+
+ if (unlikely(atomic_read(&current->tracing_graph_pause)))
+ return;
+
+ old = *parent;
+ *parent = return_hooker;
+
+ err = ftrace_push_return_trace(old, self_addr, &trace.depth,
+ frame_pointer);
+ if (err == -EBUSY) {
+ *parent = old;
+ return;
+ }
+
+ trace.func = self_addr;
+
+ /* Only trace if the calling function expects to */
+ if (!ftrace_graph_entry(&trace)) {
+ current->curr_ret_stack--;
+ *parent = old;
+ }
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */