aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2015-01-09 07:08:28 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-01-29 03:19:25 -0500
commite6d60b368b45b9be3aa068f8e5fa98c3487c9d4e (patch)
treeabe83543f72b5cd5d5de309dab8551f93c34f023 /arch/s390/kernel
parent61f552141c9c0e88b3fdc7046265781ffd8fa68a (diff)
s390/ftrace: hotpatch support for function tracing
Make use of gcc's hotpatch support to generate better code for ftrace function tracing. The generated code now contains only a six byte nop in each function prologue instead of a 24 byte code block which will be runtime patched to support function tracing. With the new code generation the runtime overhead for supporting function tracing is close to zero, while the original code did show a significant performance impact. Acked-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/Makefile4
-rw-r--r--arch/s390/kernel/ftrace.c15
-rw-r--r--arch/s390/kernel/kprobes.c3
-rw-r--r--arch/s390/kernel/mcount.S2
4 files changed, 20 insertions, 4 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 204c43a4c245..31fab2676fe9 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -4,8 +4,8 @@
4 4
5ifdef CONFIG_FUNCTION_TRACER 5ifdef CONFIG_FUNCTION_TRACER
6# Don't trace early setup code and tracing code 6# Don't trace early setup code and tracing code
7CFLAGS_REMOVE_early.o = -pg 7CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE)
8CFLAGS_REMOVE_ftrace.o = -pg 8CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
9endif 9endif
10 10
11# 11#
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index 3dabcae40e04..82c19899574f 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -46,6 +46,13 @@
46 * lg %r14,8(%r15) # offset 18 46 * lg %r14,8(%r15) # offset 18
47 * The jg instruction branches to offset 24 to skip as many instructions 47 * The jg instruction branches to offset 24 to skip as many instructions
48 * as possible. 48 * as possible.
49 * In case we use gcc's hotpatch feature the original and also the disabled
50 * function prologue contains only a single six byte instruction and looks
51 * like this:
52 * > brcl 0,0 # offset 0
53 * To enable ftrace the code gets patched like above and afterwards looks
54 * like this:
55 * > brasl %r0,ftrace_caller # offset 0
49 */ 56 */
50 57
51unsigned long ftrace_plt; 58unsigned long ftrace_plt;
@@ -64,9 +71,15 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
64 if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) 71 if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old)))
65 return -EFAULT; 72 return -EFAULT;
66 if (addr == MCOUNT_ADDR) { 73 if (addr == MCOUNT_ADDR) {
67 /* Initial code replacement; we expect to see stg r14,8(r15) */ 74 /* Initial code replacement */
75#ifdef CC_USING_HOTPATCH
76 /* We expect to see brcl 0,0 */
77 ftrace_generate_nop_insn(&orig);
78#else
79 /* We expect to see stg r14,8(r15) */
68 orig.opc = 0xe3e0; 80 orig.opc = 0xe3e0;
69 orig.disp = 0xf0080024; 81 orig.disp = 0xf0080024;
82#endif
70 ftrace_generate_nop_insn(&new); 83 ftrace_generate_nop_insn(&new);
71 } else if (old.opc == BREAKPOINT_INSTRUCTION) { 84 } else if (old.opc == BREAKPOINT_INSTRUCTION) {
72 /* 85 /*
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 1e4c710dfb92..f516edc1fbe3 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -69,7 +69,8 @@ static void copy_instruction(struct kprobe *p)
69 /* 69 /*
70 * If kprobes patches the instruction that is morphed by 70 * If kprobes patches the instruction that is morphed by
71 * ftrace make sure that kprobes always sees the branch 71 * ftrace make sure that kprobes always sees the branch
72 * "jg .+24" that skips the mcount block 72 * "jg .+24" that skips the mcount block or the "brcl 0,0"
73 * in case of hotpatch.
73 */ 74 */
74 ftrace_generate_nop_insn((struct ftrace_insn *)p->ainsn.insn); 75 ftrace_generate_nop_insn((struct ftrace_insn *)p->ainsn.insn);
75 p->ainsn.is_ftrace_insn = 1; 76 p->ainsn.is_ftrace_insn = 1;
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
index b6dfc5bfcb89..e499370fbccb 100644
--- a/arch/s390/kernel/mcount.S
+++ b/arch/s390/kernel/mcount.S
@@ -27,7 +27,9 @@ ENTRY(ftrace_caller)
27 .globl ftrace_regs_caller 27 .globl ftrace_regs_caller
28 .set ftrace_regs_caller,ftrace_caller 28 .set ftrace_regs_caller,ftrace_caller
29 lgr %r1,%r15 29 lgr %r1,%r15
30#ifndef CC_USING_HOTPATCH
30 aghi %r0,MCOUNT_RETURN_FIXUP 31 aghi %r0,MCOUNT_RETURN_FIXUP
32#endif
31 aghi %r15,-STACK_FRAME_SIZE 33 aghi %r15,-STACK_FRAME_SIZE
32 stg %r1,__SF_BACKCHAIN(%r15) 34 stg %r1,__SF_BACKCHAIN(%r15)
33 stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15) 35 stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15)