diff options
author | Steven Rostedt <srostedt@redhat.com> | 2008-05-12 15:20:43 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-23 14:33:47 -0400 |
commit | d61f82d06672f57fca410da6f7fffd15867db622 (patch) | |
tree | 62ef5573934eaa638c0d39a45d789691aecbd7d3 /include/linux | |
parent | 3c1720f00bb619302ba19d55986ab565e74d06db (diff) |
ftrace: use dynamic patching for updating mcount calls
This patch replaces the indirect call to the mcount function
pointer with a direct call that will be patched by the
dynamic ftrace routines.
On boot up, the mcount function calls the ftace_stub function.
When the dynamic ftrace code is initialized, the ftrace_stub
is replaced with a call to the ftrace_record_ip, which records
the instruction pointers of the locations that call it.
Later, the ftraced daemon will call kstop_machine and patch all
the locations to nops.
When a ftrace is enabled, the original calls to mcount will now
be set top call ftrace_caller, which will do a direct call
to the registered ftrace function. This direct call is also patched
when the function that should be called is updated.
All patching is performed by a kstop_machine routine to prevent any
type of race conditions that is associated with modifying code
on the fly.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/ftrace.h | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index d509ad6c9cb8..b0dd0093058f 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h | |||
@@ -56,9 +56,14 @@ struct dyn_ftrace { | |||
56 | extern int ftrace_ip_converted(unsigned long ip); | 56 | extern int ftrace_ip_converted(unsigned long ip); |
57 | extern unsigned char *ftrace_nop_replace(void); | 57 | extern unsigned char *ftrace_nop_replace(void); |
58 | extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr); | 58 | extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr); |
59 | extern int ftrace_dyn_arch_init(void); | 59 | extern int ftrace_dyn_arch_init(void *data); |
60 | extern int ftrace_mcount_set(unsigned long *data); | ||
60 | extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, | 61 | extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, |
61 | unsigned char *new_code); | 62 | unsigned char *new_code); |
63 | extern int ftrace_update_ftrace_func(ftrace_func_t func); | ||
64 | extern void ftrace_caller(void); | ||
65 | extern void ftrace_call(void); | ||
66 | extern void mcount_call(void); | ||
62 | #endif | 67 | #endif |
63 | 68 | ||
64 | #ifdef CONFIG_FRAME_POINTER | 69 | #ifdef CONFIG_FRAME_POINTER |