diff options
author | Tim Bird <tim.bird@am.sony.com> | 2010-10-09 12:54:38 -0400 |
---|---|---|
committer | Rabin Vincent <rabin@rab.in> | 2010-11-19 11:13:27 -0500 |
commit | 376cfa8730c08c0394d0aa1d4a80fd8c9971f323 (patch) | |
tree | f1384eb77981241b1ab1028a50b94382c2c6e723 /arch/arm/kernel/ftrace.c | |
parent | d3b9dc9dd2b994f396741f7086ffe7a48bacb165 (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.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 971ac8c36ea7..7a702a502871 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #define NOP 0xe8bd4000 /* pop {lr} */ | 24 | #define NOP 0xe8bd4000 /* pop {lr} */ |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
27 | #ifdef CONFIG_OLD_MCOUNT | 28 | #ifdef CONFIG_OLD_MCOUNT |
28 | #define OLD_MCOUNT_ADDR ((unsigned long) mcount) | 29 | #define OLD_MCOUNT_ADDR ((unsigned long) mcount) |
29 | #define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old) | 30 | #define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old) |
@@ -193,3 +194,36 @@ int __init ftrace_dyn_arch_init(void *data) | |||
193 | 194 | ||
194 | return 0; | 195 | return 0; |
195 | } | 196 | } |
197 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
198 | |||
199 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
200 | void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | ||
201 | unsigned long frame_pointer) | ||
202 | { | ||
203 | unsigned long return_hooker = (unsigned long) &return_to_handler; | ||
204 | struct ftrace_graph_ent trace; | ||
205 | unsigned long old; | ||
206 | int err; | ||
207 | |||
208 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) | ||
209 | return; | ||
210 | |||
211 | old = *parent; | ||
212 | *parent = return_hooker; | ||
213 | |||
214 | err = ftrace_push_return_trace(old, self_addr, &trace.depth, | ||
215 | frame_pointer); | ||
216 | if (err == -EBUSY) { | ||
217 | *parent = old; | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | trace.func = self_addr; | ||
222 | |||
223 | /* Only trace if the calling function expects to */ | ||
224 | if (!ftrace_graph_entry(&trace)) { | ||
225 | current->curr_ret_stack--; | ||
226 | *parent = old; | ||
227 | } | ||
228 | } | ||
229 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||