Commit bb725340 authored by Steven Rostedt's avatar Steven Rostedt Committed by Benjamin Herrenschmidt

powerpc64, ftrace: save toc only on modules for function graph

The TOCS used by modules are different than the one used by
the core kernel code. The function graph tracer must save and
restore the TOC whenever it traces a module call. But this
is an added overhead to burden the majority of core kernel
code being traced.

Benjamin Herrenschmidt suggested in testing the entry of
the call to tell if it is a core kernel function or a module.
He recommended using the REGION_ID() macro to perform this test.

This patch implements Benjamin's idea, and uses a different
return_to_handler routine dependent on if the entry is a core
kernel function or not. The module version saves the TOC, where as
the core kernel version does not.

Geoff Lavand tested on PS3.
Tested-by: default avatarGeoff Levand <geoffrey.levand@am.sony.com>
Acked-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarSteven Rostedt <srostedt@redhat.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 46542888
...@@ -970,6 +970,28 @@ _GLOBAL(ftrace_graph_caller) ...@@ -970,6 +970,28 @@ _GLOBAL(ftrace_graph_caller)
blr blr
_GLOBAL(return_to_handler) _GLOBAL(return_to_handler)
/* need to save return values */
std r4, -24(r1)
std r3, -16(r1)
std r31, -8(r1)
mr r31, r1
stdu r1, -112(r1)
bl .ftrace_return_to_handler
nop
/* return value has real return address */
mtlr r3
ld r1, 0(r1)
ld r4, -24(r1)
ld r3, -16(r1)
ld r31, -8(r1)
/* Jump back to real return address */
blr
_GLOBAL(mod_return_to_handler)
/* need to save return values */ /* need to save return values */
std r4, -32(r1) std r4, -32(r1)
std r3, -24(r1) std r3, -24(r1)
...@@ -979,7 +1001,10 @@ _GLOBAL(return_to_handler) ...@@ -979,7 +1001,10 @@ _GLOBAL(return_to_handler)
mr r31, r1 mr r31, r1
stdu r1, -112(r1) stdu r1, -112(r1)
/* update the TOC */ /*
* We are in a module using the module's TOC.
* Switch to our TOC to run inside the core kernel.
*/
LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler) LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler)
ld r2, 8(r4) ld r2, 8(r4)
......
...@@ -567,6 +567,10 @@ int ftrace_disable_ftrace_graph_caller(void) ...@@ -567,6 +567,10 @@ int ftrace_disable_ftrace_graph_caller(void)
} }
#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_PPC64
extern void mod_return_to_handler(void);
#endif
/* /*
* Hook the return address and push it in the stack of return addrs * Hook the return address and push it in the stack of return addrs
* in current thread info. * in current thread info.
...@@ -577,12 +581,17 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) ...@@ -577,12 +581,17 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
unsigned long long calltime; unsigned long long calltime;
int faulted; int faulted;
struct ftrace_graph_ent trace; struct ftrace_graph_ent trace;
unsigned long return_hooker = (unsigned long) unsigned long return_hooker = (unsigned long)&return_to_handler;
&return_to_handler;
if (unlikely(atomic_read(&current->tracing_graph_pause))) if (unlikely(atomic_read(&current->tracing_graph_pause)))
return; return;
#if CONFIG_PPC64
/* non core kernel code needs to save and restore the TOC */
if (REGION_ID(self_addr) != KERNEL_REGION_ID)
return_hooker = (unsigned long)&mod_return_to_handler;
#endif
return_hooker = GET_ADDR(return_hooker); return_hooker = GET_ADDR(return_hooker);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment