aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-24 13:08:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-01-24 13:08:16 -0500
commit03fae44b41062419aedcf2ae4ad68034f440f862 (patch)
tree5e5f2c73feb4e0e050ae7fc1d258092c9922090b
parentce30f264b33d9e3d27e34638976c52b578648b92 (diff)
parent2ee5b92a2598d9e403337185fdf88f661dee8616 (diff)
Merge tag 'trace-v4.15-rc9' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing fixes from Steven Rostedt: "With the new ORC unwinder, ftrace stack tracing became disfunctional. One was that ORC didn't know how to handle the ftrace callbacks in general (which Josh fixed). The other was that ORC would just bail if it hit a dynamically allocated trampoline. Which means all ftrace stack tracing that happens from the function tracer would produce no results (that includes killing the max stack size tracer). I added a check to the ORC unwinder to see if the trampoline belonged to ftrace, and if it did, use the orc entry of the static trampoline that was used to create the dynamic one (it would be identical). Finally, I noticed that the skip values of the stack tracing were out of whack. I went through and fixed them up" * tag 'trace-v4.15-rc9' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Update stack trace skipping for ORC unwinder ftrace, orc, x86: Handle ftrace dynamically allocated trampolines x86/ftrace: Fix ORC unwinding from ftrace handlers
-rw-r--r--arch/x86/kernel/Makefile5
-rw-r--r--arch/x86/kernel/ftrace_64.S24
-rw-r--r--arch/x86/kernel/unwind_orc.c48
-rw-r--r--include/linux/ftrace.h2
-rw-r--r--kernel/trace/ftrace.c29
-rw-r--r--kernel/trace/trace.c34
-rw-r--r--kernel/trace/trace_events_trigger.c13
-rw-r--r--kernel/trace/trace_functions.c49
8 files changed, 152 insertions, 52 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 81bb565f4497..7e2baf7304ae 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -29,10 +29,13 @@ KASAN_SANITIZE_stacktrace.o := n
29KASAN_SANITIZE_paravirt.o := n 29KASAN_SANITIZE_paravirt.o := n
30 30
31OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y 31OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y
32OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o := y
33OBJECT_FILES_NON_STANDARD_test_nx.o := y 32OBJECT_FILES_NON_STANDARD_test_nx.o := y
34OBJECT_FILES_NON_STANDARD_paravirt_patch_$(BITS).o := y 33OBJECT_FILES_NON_STANDARD_paravirt_patch_$(BITS).o := y
35 34
35ifdef CONFIG_FRAME_POINTER
36OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o := y
37endif
38
36# If instrumentation of this dir is enabled, boot hangs during first second. 39# If instrumentation of this dir is enabled, boot hangs during first second.
37# Probably could be more selective here, but note that files related to irqs, 40# Probably could be more selective here, but note that files related to irqs,
38# boot, dumpstack/stacktrace, etc are either non-interesting or can lead to 41# boot, dumpstack/stacktrace, etc are either non-interesting or can lead to
diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S
index 7cb8ba08beb9..ef61f540cf0a 100644
--- a/arch/x86/kernel/ftrace_64.S
+++ b/arch/x86/kernel/ftrace_64.S
@@ -8,6 +8,7 @@
8#include <asm/ftrace.h> 8#include <asm/ftrace.h>
9#include <asm/export.h> 9#include <asm/export.h>
10#include <asm/nospec-branch.h> 10#include <asm/nospec-branch.h>
11#include <asm/unwind_hints.h>
11 12
12 .code64 13 .code64
13 .section .entry.text, "ax" 14 .section .entry.text, "ax"
@@ -20,7 +21,6 @@ EXPORT_SYMBOL(__fentry__)
20EXPORT_SYMBOL(mcount) 21EXPORT_SYMBOL(mcount)
21#endif 22#endif
22 23
23/* All cases save the original rbp (8 bytes) */
24#ifdef CONFIG_FRAME_POINTER 24#ifdef CONFIG_FRAME_POINTER
25# ifdef CC_USING_FENTRY 25# ifdef CC_USING_FENTRY
26/* Save parent and function stack frames (rip and rbp) */ 26/* Save parent and function stack frames (rip and rbp) */
@@ -31,7 +31,7 @@ EXPORT_SYMBOL(mcount)
31# endif 31# endif
32#else 32#else
33/* No need to save a stack frame */ 33/* No need to save a stack frame */
34# define MCOUNT_FRAME_SIZE 8 34# define MCOUNT_FRAME_SIZE 0
35#endif /* CONFIG_FRAME_POINTER */ 35#endif /* CONFIG_FRAME_POINTER */
36 36
37/* Size of stack used to save mcount regs in save_mcount_regs */ 37/* Size of stack used to save mcount regs in save_mcount_regs */
@@ -64,10 +64,10 @@ EXPORT_SYMBOL(mcount)
64 */ 64 */
65.macro save_mcount_regs added=0 65.macro save_mcount_regs added=0
66 66
67 /* Always save the original rbp */ 67#ifdef CONFIG_FRAME_POINTER
68 /* Save the original rbp */
68 pushq %rbp 69 pushq %rbp
69 70
70#ifdef CONFIG_FRAME_POINTER
71 /* 71 /*
72 * Stack traces will stop at the ftrace trampoline if the frame pointer 72 * Stack traces will stop at the ftrace trampoline if the frame pointer
73 * is not set up properly. If fentry is used, we need to save a frame 73 * is not set up properly. If fentry is used, we need to save a frame
@@ -105,7 +105,11 @@ EXPORT_SYMBOL(mcount)
105 * Save the original RBP. Even though the mcount ABI does not 105 * Save the original RBP. Even though the mcount ABI does not
106 * require this, it helps out callers. 106 * require this, it helps out callers.
107 */ 107 */
108#ifdef CONFIG_FRAME_POINTER
108 movq MCOUNT_REG_SIZE-8(%rsp), %rdx 109 movq MCOUNT_REG_SIZE-8(%rsp), %rdx
110#else
111 movq %rbp, %rdx
112#endif
109 movq %rdx, RBP(%rsp) 113 movq %rdx, RBP(%rsp)
110 114
111 /* Copy the parent address into %rsi (second parameter) */ 115 /* Copy the parent address into %rsi (second parameter) */
@@ -148,7 +152,7 @@ EXPORT_SYMBOL(mcount)
148 152
149ENTRY(function_hook) 153ENTRY(function_hook)
150 retq 154 retq
151END(function_hook) 155ENDPROC(function_hook)
152 156
153ENTRY(ftrace_caller) 157ENTRY(ftrace_caller)
154 /* save_mcount_regs fills in first two parameters */ 158 /* save_mcount_regs fills in first two parameters */
@@ -184,7 +188,7 @@ GLOBAL(ftrace_graph_call)
184/* This is weak to keep gas from relaxing the jumps */ 188/* This is weak to keep gas from relaxing the jumps */
185WEAK(ftrace_stub) 189WEAK(ftrace_stub)
186 retq 190 retq
187END(ftrace_caller) 191ENDPROC(ftrace_caller)
188 192
189ENTRY(ftrace_regs_caller) 193ENTRY(ftrace_regs_caller)
190 /* Save the current flags before any operations that can change them */ 194 /* Save the current flags before any operations that can change them */
@@ -255,7 +259,7 @@ GLOBAL(ftrace_regs_caller_end)
255 259
256 jmp ftrace_epilogue 260 jmp ftrace_epilogue
257 261
258END(ftrace_regs_caller) 262ENDPROC(ftrace_regs_caller)
259 263
260 264
261#else /* ! CONFIG_DYNAMIC_FTRACE */ 265#else /* ! CONFIG_DYNAMIC_FTRACE */
@@ -313,9 +317,10 @@ ENTRY(ftrace_graph_caller)
313 restore_mcount_regs 317 restore_mcount_regs
314 318
315 retq 319 retq
316END(ftrace_graph_caller) 320ENDPROC(ftrace_graph_caller)
317 321
318GLOBAL(return_to_handler) 322ENTRY(return_to_handler)
323 UNWIND_HINT_EMPTY
319 subq $24, %rsp 324 subq $24, %rsp
320 325
321 /* Save the return values */ 326 /* Save the return values */
@@ -330,4 +335,5 @@ GLOBAL(return_to_handler)
330 movq (%rsp), %rax 335 movq (%rsp), %rax
331 addq $24, %rsp 336 addq $24, %rsp
332 JMP_NOSPEC %rdi 337 JMP_NOSPEC %rdi
338END(return_to_handler)
333#endif 339#endif
diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
index be86a865087a..1f9188f5357c 100644
--- a/arch/x86/kernel/unwind_orc.c
+++ b/arch/x86/kernel/unwind_orc.c
@@ -74,8 +74,50 @@ static struct orc_entry *orc_module_find(unsigned long ip)
74} 74}
75#endif 75#endif
76 76
77#ifdef CONFIG_DYNAMIC_FTRACE
78static struct orc_entry *orc_find(unsigned long ip);
79
80/*
81 * Ftrace dynamic trampolines do not have orc entries of their own.
82 * But they are copies of the ftrace entries that are static and
83 * defined in ftrace_*.S, which do have orc entries.
84 *
85 * If the undwinder comes across a ftrace trampoline, then find the
86 * ftrace function that was used to create it, and use that ftrace
87 * function's orc entrie, as the placement of the return code in
88 * the stack will be identical.
89 */
90static struct orc_entry *orc_ftrace_find(unsigned long ip)
91{
92 struct ftrace_ops *ops;
93 unsigned long caller;
94
95 ops = ftrace_ops_trampoline(ip);
96 if (!ops)
97 return NULL;
98
99 if (ops->flags & FTRACE_OPS_FL_SAVE_REGS)
100 caller = (unsigned long)ftrace_regs_call;
101 else
102 caller = (unsigned long)ftrace_call;
103
104 /* Prevent unlikely recursion */
105 if (ip == caller)
106 return NULL;
107
108 return orc_find(caller);
109}
110#else
111static struct orc_entry *orc_ftrace_find(unsigned long ip)
112{
113 return NULL;
114}
115#endif
116
77static struct orc_entry *orc_find(unsigned long ip) 117static struct orc_entry *orc_find(unsigned long ip)
78{ 118{
119 static struct orc_entry *orc;
120
79 if (!orc_init) 121 if (!orc_init)
80 return NULL; 122 return NULL;
81 123
@@ -111,7 +153,11 @@ static struct orc_entry *orc_find(unsigned long ip)
111 __stop_orc_unwind_ip - __start_orc_unwind_ip, ip); 153 __stop_orc_unwind_ip - __start_orc_unwind_ip, ip);
112 154
113 /* Module lookup: */ 155 /* Module lookup: */
114 return orc_module_find(ip); 156 orc = orc_module_find(ip);
157 if (orc)
158 return orc;
159
160 return orc_ftrace_find(ip);
115} 161}
116 162
117static void orc_sort_swap(void *_a, void *_b, int size) 163static void orc_sort_swap(void *_a, void *_b, int size)
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 2bab81951ced..3319df9727aa 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -332,6 +332,8 @@ extern int ftrace_text_reserved(const void *start, const void *end);
332 332
333extern int ftrace_nr_registered_ops(void); 333extern int ftrace_nr_registered_ops(void);
334 334
335struct ftrace_ops *ftrace_ops_trampoline(unsigned long addr);
336
335bool is_ftrace_trampoline(unsigned long addr); 337bool is_ftrace_trampoline(unsigned long addr);
336 338
337/* 339/*
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index ccdf3664e4a9..554b517c61a0 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1119,15 +1119,11 @@ static struct ftrace_ops global_ops = {
1119}; 1119};
1120 1120
1121/* 1121/*
1122 * This is used by __kernel_text_address() to return true if the 1122 * Used by the stack undwinder to know about dynamic ftrace trampolines.
1123 * address is on a dynamically allocated trampoline that would
1124 * not return true for either core_kernel_text() or
1125 * is_module_text_address().
1126 */ 1123 */
1127bool is_ftrace_trampoline(unsigned long addr) 1124struct ftrace_ops *ftrace_ops_trampoline(unsigned long addr)
1128{ 1125{
1129 struct ftrace_ops *op; 1126 struct ftrace_ops *op = NULL;
1130 bool ret = false;
1131 1127
1132 /* 1128 /*
1133 * Some of the ops may be dynamically allocated, 1129 * Some of the ops may be dynamically allocated,
@@ -1144,15 +1140,24 @@ bool is_ftrace_trampoline(unsigned long addr)
1144 if (op->trampoline && op->trampoline_size) 1140 if (op->trampoline && op->trampoline_size)
1145 if (addr >= op->trampoline && 1141 if (addr >= op->trampoline &&
1146 addr < op->trampoline + op->trampoline_size) { 1142 addr < op->trampoline + op->trampoline_size) {
1147 ret = true; 1143 preempt_enable_notrace();
1148 goto out; 1144 return op;
1149 } 1145 }
1150 } while_for_each_ftrace_op(op); 1146 } while_for_each_ftrace_op(op);
1151
1152 out:
1153 preempt_enable_notrace(); 1147 preempt_enable_notrace();
1154 1148
1155 return ret; 1149 return NULL;
1150}
1151
1152/*
1153 * This is used by __kernel_text_address() to return true if the
1154 * address is on a dynamically allocated trampoline that would
1155 * not return true for either core_kernel_text() or
1156 * is_module_text_address().
1157 */
1158bool is_ftrace_trampoline(unsigned long addr)
1159{
1160 return ftrace_ops_trampoline(addr) != NULL;
1156} 1161}
1157 1162
1158struct ftrace_page { 1163struct ftrace_page {
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2a8d8a294345..8e3f20a18a06 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2374,6 +2374,15 @@ void trace_event_buffer_commit(struct trace_event_buffer *fbuffer)
2374} 2374}
2375EXPORT_SYMBOL_GPL(trace_event_buffer_commit); 2375EXPORT_SYMBOL_GPL(trace_event_buffer_commit);
2376 2376
2377/*
2378 * Skip 3:
2379 *
2380 * trace_buffer_unlock_commit_regs()
2381 * trace_event_buffer_commit()
2382 * trace_event_raw_event_xxx()
2383*/
2384# define STACK_SKIP 3
2385
2377void trace_buffer_unlock_commit_regs(struct trace_array *tr, 2386void trace_buffer_unlock_commit_regs(struct trace_array *tr,
2378 struct ring_buffer *buffer, 2387 struct ring_buffer *buffer,
2379 struct ring_buffer_event *event, 2388 struct ring_buffer_event *event,
@@ -2383,16 +2392,12 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
2383 __buffer_unlock_commit(buffer, event); 2392 __buffer_unlock_commit(buffer, event);
2384 2393
2385 /* 2394 /*
2386 * If regs is not set, then skip the following callers: 2395 * If regs is not set, then skip the necessary functions.
2387 * trace_buffer_unlock_commit_regs
2388 * event_trigger_unlock_commit
2389 * trace_event_buffer_commit
2390 * trace_event_raw_event_sched_switch
2391 * Note, we can still get here via blktrace, wakeup tracer 2396 * Note, we can still get here via blktrace, wakeup tracer
2392 * and mmiotrace, but that's ok if they lose a function or 2397 * and mmiotrace, but that's ok if they lose a function or
2393 * two. They are that meaningful. 2398 * two. They are not that meaningful.
2394 */ 2399 */
2395 ftrace_trace_stack(tr, buffer, flags, regs ? 0 : 4, pc, regs); 2400 ftrace_trace_stack(tr, buffer, flags, regs ? 0 : STACK_SKIP, pc, regs);
2396 ftrace_trace_userstack(buffer, flags, pc); 2401 ftrace_trace_userstack(buffer, flags, pc);
2397} 2402}
2398 2403
@@ -2579,11 +2584,13 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer,
2579 trace.skip = skip; 2584 trace.skip = skip;
2580 2585
2581 /* 2586 /*
2582 * Add two, for this function and the call to save_stack_trace() 2587 * Add one, for this function and the call to save_stack_trace()
2583 * If regs is set, then these functions will not be in the way. 2588 * If regs is set, then these functions will not be in the way.
2584 */ 2589 */
2590#ifndef CONFIG_UNWINDER_ORC
2585 if (!regs) 2591 if (!regs)
2586 trace.skip += 2; 2592 trace.skip++;
2593#endif
2587 2594
2588 /* 2595 /*
2589 * Since events can happen in NMIs there's no safe way to 2596 * Since events can happen in NMIs there's no safe way to
@@ -2711,11 +2718,10 @@ void trace_dump_stack(int skip)
2711 2718
2712 local_save_flags(flags); 2719 local_save_flags(flags);
2713 2720
2714 /* 2721#ifndef CONFIG_UNWINDER_ORC
2715 * Skip 3 more, seems to get us at the caller of 2722 /* Skip 1 to skip this function. */
2716 * this function. 2723 skip++;
2717 */ 2724#endif
2718 skip += 3;
2719 __ftrace_trace_stack(global_trace.trace_buffer.buffer, 2725 __ftrace_trace_stack(global_trace.trace_buffer.buffer,
2720 flags, skip, preempt_count(), NULL); 2726 flags, skip, preempt_count(), NULL);
2721} 2727}
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index f2ac9d44f6c4..87411482a46f 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -1123,13 +1123,22 @@ static __init int register_trigger_snapshot_cmd(void) { return 0; }
1123#endif /* CONFIG_TRACER_SNAPSHOT */ 1123#endif /* CONFIG_TRACER_SNAPSHOT */
1124 1124
1125#ifdef CONFIG_STACKTRACE 1125#ifdef CONFIG_STACKTRACE
1126#ifdef CONFIG_UNWINDER_ORC
1127/* Skip 2:
1128 * event_triggers_post_call()
1129 * trace_event_raw_event_xxx()
1130 */
1131# define STACK_SKIP 2
1132#else
1126/* 1133/*
1127 * Skip 3: 1134 * Skip 4:
1128 * stacktrace_trigger() 1135 * stacktrace_trigger()
1129 * event_triggers_post_call() 1136 * event_triggers_post_call()
1137 * trace_event_buffer_commit()
1130 * trace_event_raw_event_xxx() 1138 * trace_event_raw_event_xxx()
1131 */ 1139 */
1132#define STACK_SKIP 3 1140#define STACK_SKIP 4
1141#endif
1133 1142
1134static void 1143static void
1135stacktrace_trigger(struct event_trigger_data *data, void *rec) 1144stacktrace_trigger(struct event_trigger_data *data, void *rec)
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 27f7ad12c4b1..b611cd36e22d 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -154,6 +154,24 @@ function_trace_call(unsigned long ip, unsigned long parent_ip,
154 preempt_enable_notrace(); 154 preempt_enable_notrace();
155} 155}
156 156
157#ifdef CONFIG_UNWINDER_ORC
158/*
159 * Skip 2:
160 *
161 * function_stack_trace_call()
162 * ftrace_call()
163 */
164#define STACK_SKIP 2
165#else
166/*
167 * Skip 3:
168 * __trace_stack()
169 * function_stack_trace_call()
170 * ftrace_call()
171 */
172#define STACK_SKIP 3
173#endif
174
157static void 175static void
158function_stack_trace_call(unsigned long ip, unsigned long parent_ip, 176function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
159 struct ftrace_ops *op, struct pt_regs *pt_regs) 177 struct ftrace_ops *op, struct pt_regs *pt_regs)
@@ -180,15 +198,7 @@ function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
180 if (likely(disabled == 1)) { 198 if (likely(disabled == 1)) {
181 pc = preempt_count(); 199 pc = preempt_count();
182 trace_function(tr, ip, parent_ip, flags, pc); 200 trace_function(tr, ip, parent_ip, flags, pc);
183 /* 201 __trace_stack(tr, flags, STACK_SKIP, pc);
184 * skip over 5 funcs:
185 * __ftrace_trace_stack,
186 * __trace_stack,
187 * function_stack_trace_call
188 * ftrace_list_func
189 * ftrace_call
190 */
191 __trace_stack(tr, flags, 5, pc);
192 } 202 }
193 203
194 atomic_dec(&data->disabled); 204 atomic_dec(&data->disabled);
@@ -367,14 +377,27 @@ ftrace_traceoff(unsigned long ip, unsigned long parent_ip,
367 tracer_tracing_off(tr); 377 tracer_tracing_off(tr);
368} 378}
369 379
380#ifdef CONFIG_UNWINDER_ORC
370/* 381/*
371 * Skip 4: 382 * Skip 3:
383 *
384 * function_trace_probe_call()
385 * ftrace_ops_assist_func()
386 * ftrace_call()
387 */
388#define FTRACE_STACK_SKIP 3
389#else
390/*
391 * Skip 5:
392 *
393 * __trace_stack()
372 * ftrace_stacktrace() 394 * ftrace_stacktrace()
373 * function_trace_probe_call() 395 * function_trace_probe_call()
374 * ftrace_ops_list_func() 396 * ftrace_ops_assist_func()
375 * ftrace_call() 397 * ftrace_call()
376 */ 398 */
377#define STACK_SKIP 4 399#define FTRACE_STACK_SKIP 5
400#endif
378 401
379static __always_inline void trace_stack(struct trace_array *tr) 402static __always_inline void trace_stack(struct trace_array *tr)
380{ 403{
@@ -384,7 +407,7 @@ static __always_inline void trace_stack(struct trace_array *tr)
384 local_save_flags(flags); 407 local_save_flags(flags);
385 pc = preempt_count(); 408 pc = preempt_count();
386 409
387 __trace_stack(tr, flags, STACK_SKIP, pc); 410 __trace_stack(tr, flags, FTRACE_STACK_SKIP, pc);
388} 411}
389 412
390static void 413static void