aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/ftrace.c
diff options
context:
space:
mode:
authorWu Zhangjin <wuzhangjin@gmail.com>2009-11-20 20:34:38 +0800
committerRalf Baechle <ralf@linux-mips.org>2009-12-17 01:57:27 +0000
commit7326c4e567b50e689d13c04d58aeffa515277ebb (patch)
treeab3ecf92cf84decb1ff7b419920222770024125b /arch/mips/kernel/ftrace.c
parentfc49a3be2be7a0cd44fcd3b37557d6d92cae59b1 (diff)
downloadkernel_samsung_tuna-7326c4e567b50e689d13c04d58aeffa515277ebb.zip
kernel_samsung_tuna-7326c4e567b50e689d13c04d58aeffa515277ebb.tar.gz
kernel_samsung_tuna-7326c4e567b50e689d13c04d58aeffa515277ebb.tar.bz2
MIPS: Tracing: Make function graph tracer work with -mmcount-ra-address
That thread "MIPS: Add option to pass return address location to _mcount" from "David Daney <ddaney@caviumnetworks.com>" have added a new option -mmcount-ra-address to gcc(4.5) for MIPS to transfer the location of the return address to _mcount. Benefit from this new feature, function graph tracer on MIPS will be easier and safer to hijack the return address of the kernel function, which will save some overhead and make the whole thing more reliable. In this patch, at first, try to enable the option -mmcount-ra-address in arch/mips/Makefile with cc-option, if gcc support it, it will be enabled, otherwise, no side effect. and then, we need to support this new option of gcc 4.5 and also support the old gcc versions. with _mcount in the old gcc versions, it's not easy to get the location of return address(tracing: add function graph tracer support for MIPS), so, we do it in a C function: ftrace_get_parent_addr(ftrace.c), but with -mmcount-ra-address, only several instructions need to get what we want, so, I put into asm(mcount.S). and also, as the $12(t0) is used by -mmcount-ra-address for transferring the localtion of return address to _mcount, we need to save it into the stack and restore it when enabled dynamic function tracer, 'Cause we have called "ftrace_call" before "ftrace_graph_caller", which may destroy $12(t0). (Thanks to David for providing that -mcount-ra-address and giving the idea of KBUILD_MCOUNT_RA_ADDRESS, both of them have made the whole thing more beautiful!) Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Nicholas Mc Guire <der.herr@hofr.at> Cc: zhangfx@lemote.com Cc: Wu Zhangjin <wuzhangjin@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/681/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/ftrace.c')
-rw-r--r--arch/mips/kernel/ftrace.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index e363fc6..68b0670 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -148,6 +148,7 @@ int ftrace_disable_ftrace_graph_caller(void)
#endif /* !CONFIG_DYNAMIC_FTRACE */
+#ifndef KBUILD_MCOUNT_RA_ADDRESS
#define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */
#define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */
#define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
@@ -201,6 +202,8 @@ unsigned long ftrace_get_parent_addr(unsigned long self_addr,
return 0;
}
+#endif
+
/*
* Hook the return address and push it in the stack of return addrs
* in current thread info.
@@ -218,19 +221,26 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
return;
/* "parent" is the stack address saved the return address of the caller
- * of _mcount, for a leaf function not save the return address in the
- * stack address, so, we "emulate" one in _mcount's stack space, and
- * hijack it directly, but for a non-leaf function, it will save the
- * return address to the its stack space, so, we can not hijack the
- * "parent" directly, but need to find the real stack address,
+ * of _mcount.
+ *
+ * if the gcc < 4.5, a leaf function does not save the return address
+ * in the stack address, so, we "emulate" one in _mcount's stack space,
+ * and hijack it directly, but for a non-leaf function, it save the
+ * return address to the its own stack space, we can not hijack it
+ * directly, but need to find the real stack address,
* ftrace_get_parent_addr() does it!
+ *
+ * if gcc>= 4.5, with the new -mmcount-ra-address option, for a
+ * non-leaf function, the location of the return address will be saved
+ * to $12 for us, and for a leaf function, only put a zero into $12. we
+ * do it in ftrace_graph_caller of mcount.S.
*/
/* old = *parent; */
safe_load_stack(old, parent, faulted);
if (unlikely(faulted))
goto out;
-
+#ifndef KBUILD_MCOUNT_RA_ADDRESS
parent = (unsigned long *)ftrace_get_parent_addr(self_addr, old,
(unsigned long)parent,
fp);
@@ -238,7 +248,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
* ra, stop function graph tracer and return */
if (parent == 0)
goto out;
-
+#endif
/* *parent = return_hooker; */
safe_store_stack(return_hooker, parent, faulted);
if (unlikely(faulted))