aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-16 15:53:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-16 15:53:59 -0500
commita7c180aa7e76a55642e8492f28353303a50292c2 (patch)
treeb80b3575f1717a5e3a07081b5c9409805662490d /kernel/trace
parent2dbfca5a181973558277b28b1f4c36362291f5e0 (diff)
parent0daa2302968c13b657118d6ac92471f8fd2f3f28 (diff)
Merge tag 'trace-3.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing updates from Steven Rostedt: "As the merge window is still open, and this code was not as complex as I thought it might be. I'm pushing this in now. This will allow Thomas to debug his irq work for 3.20. This adds two new features: 1) Allow traceopoints to be enabled right after mm_init(). By passing in the trace_event= kernel command line parameter, tracepoints can be enabled at boot up. For debugging things like the initialization of interrupts, it is needed to have tracepoints enabled very early. People have asked about this before and this has been on my todo list. As it can be helpful for Thomas to debug his upcoming 3.20 IRQ work, I'm pushing this now. This way he can add tracepoints into the IRQ set up and have users enable them when things go wrong. 2) Have the tracepoints printed via printk() (the console) when they are triggered. If the irq code locks up or reboots the box, having the tracepoint output go into the kernel ring buffer is useless for debugging. But being able to add the tp_printk kernel command line option along with the trace_event= option will have these tracepoints printed as they occur, and that can be really useful for debugging early lock up or reboot problems. This code is not that intrusive and it passed all my tests. Thomas tried them out too and it works for his needs. Link: http://lkml.kernel.org/r/20141214201609.126831471@goodmis.org" * tag 'trace-3.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Add tp_printk cmdline to have tracepoints go to printk() tracing: Move enabling tracepoints to just after rcu_init()
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace.c25
-rw-r--r--kernel/trace/trace.h14
-rw-r--r--kernel/trace/trace_events.c42
-rw-r--r--kernel/trace/trace_syscalls.c7
4 files changed, 80 insertions, 8 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index ab76b7bcb36a..2e767972e99c 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -63,6 +63,10 @@ static bool __read_mostly tracing_selftest_running;
63 */ 63 */
64bool __read_mostly tracing_selftest_disabled; 64bool __read_mostly tracing_selftest_disabled;
65 65
66/* Pipe tracepoints to printk */
67struct trace_iterator *tracepoint_print_iter;
68int tracepoint_printk;
69
66/* For tracers that don't implement custom flags */ 70/* For tracers that don't implement custom flags */
67static struct tracer_opt dummy_tracer_opt[] = { 71static struct tracer_opt dummy_tracer_opt[] = {
68 { } 72 { }
@@ -193,6 +197,13 @@ static int __init set_trace_boot_clock(char *str)
193} 197}
194__setup("trace_clock=", set_trace_boot_clock); 198__setup("trace_clock=", set_trace_boot_clock);
195 199
200static int __init set_tracepoint_printk(char *str)
201{
202 if ((strcmp(str, "=0") != 0 && strcmp(str, "=off") != 0))
203 tracepoint_printk = 1;
204 return 1;
205}
206__setup("tp_printk", set_tracepoint_printk);
196 207
197unsigned long long ns2usecs(cycle_t nsec) 208unsigned long long ns2usecs(cycle_t nsec)
198{ 209{
@@ -6898,6 +6909,19 @@ out:
6898 return ret; 6909 return ret;
6899} 6910}
6900 6911
6912void __init trace_init(void)
6913{
6914 if (tracepoint_printk) {
6915 tracepoint_print_iter =
6916 kmalloc(sizeof(*tracepoint_print_iter), GFP_KERNEL);
6917 if (WARN_ON(!tracepoint_print_iter))
6918 tracepoint_printk = 0;
6919 }
6920 tracer_alloc_buffers();
6921 init_ftrace_syscalls();
6922 trace_event_init();
6923}
6924
6901__init static int clear_boot_tracer(void) 6925__init static int clear_boot_tracer(void)
6902{ 6926{
6903 /* 6927 /*
@@ -6917,6 +6941,5 @@ __init static int clear_boot_tracer(void)
6917 return 0; 6941 return 0;
6918} 6942}
6919 6943
6920early_initcall(tracer_alloc_buffers);
6921fs_initcall(tracer_init_debugfs); 6944fs_initcall(tracer_init_debugfs);
6922late_initcall(clear_boot_tracer); 6945late_initcall(clear_boot_tracer);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 3255dfb054a0..8de48bac1ce2 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1301,4 +1301,18 @@ int perf_ftrace_event_register(struct ftrace_event_call *call,
1301#define perf_ftrace_event_register NULL 1301#define perf_ftrace_event_register NULL
1302#endif 1302#endif
1303 1303
1304#ifdef CONFIG_FTRACE_SYSCALLS
1305void init_ftrace_syscalls(void);
1306#else
1307static inline void init_ftrace_syscalls(void) { }
1308#endif
1309
1310#ifdef CONFIG_EVENT_TRACING
1311void trace_event_init(void);
1312#else
1313static inline void __init trace_event_init(void) { }
1314#endif
1315
1316extern struct trace_iterator *tracepoint_print_iter;
1317
1304#endif /* _LINUX_KERNEL_TRACE_H */ 1318#endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index d0e4f92b5eb6..366a78a3e61e 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -212,8 +212,40 @@ void *ftrace_event_buffer_reserve(struct ftrace_event_buffer *fbuffer,
212} 212}
213EXPORT_SYMBOL_GPL(ftrace_event_buffer_reserve); 213EXPORT_SYMBOL_GPL(ftrace_event_buffer_reserve);
214 214
215static DEFINE_SPINLOCK(tracepoint_iter_lock);
216
217static void output_printk(struct ftrace_event_buffer *fbuffer)
218{
219 struct ftrace_event_call *event_call;
220 struct trace_event *event;
221 unsigned long flags;
222 struct trace_iterator *iter = tracepoint_print_iter;
223
224 if (!iter)
225 return;
226
227 event_call = fbuffer->ftrace_file->event_call;
228 if (!event_call || !event_call->event.funcs ||
229 !event_call->event.funcs->trace)
230 return;
231
232 event = &fbuffer->ftrace_file->event_call->event;
233
234 spin_lock_irqsave(&tracepoint_iter_lock, flags);
235 trace_seq_init(&iter->seq);
236 iter->ent = fbuffer->entry;
237 event_call->event.funcs->trace(iter, 0, event);
238 trace_seq_putc(&iter->seq, 0);
239 printk("%s", iter->seq.buffer);
240
241 spin_unlock_irqrestore(&tracepoint_iter_lock, flags);
242}
243
215void ftrace_event_buffer_commit(struct ftrace_event_buffer *fbuffer) 244void ftrace_event_buffer_commit(struct ftrace_event_buffer *fbuffer)
216{ 245{
246 if (tracepoint_printk)
247 output_printk(fbuffer);
248
217 event_trigger_unlock_commit(fbuffer->ftrace_file, fbuffer->buffer, 249 event_trigger_unlock_commit(fbuffer->ftrace_file, fbuffer->buffer,
218 fbuffer->event, fbuffer->entry, 250 fbuffer->event, fbuffer->entry,
219 fbuffer->flags, fbuffer->pc); 251 fbuffer->flags, fbuffer->pc);
@@ -2480,8 +2512,14 @@ static __init int event_trace_init(void)
2480#endif 2512#endif
2481 return 0; 2513 return 0;
2482} 2514}
2483early_initcall(event_trace_memsetup); 2515
2484core_initcall(event_trace_enable); 2516void __init trace_event_init(void)
2517{
2518 event_trace_memsetup();
2519 init_ftrace_syscalls();
2520 event_trace_enable();
2521}
2522
2485fs_initcall(event_trace_init); 2523fs_initcall(event_trace_init);
2486 2524
2487#ifdef CONFIG_FTRACE_STARTUP_TEST 2525#ifdef CONFIG_FTRACE_STARTUP_TEST
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index dfe00a4f3f3e..c6ee36fcbf90 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -514,7 +514,7 @@ unsigned long __init __weak arch_syscall_addr(int nr)
514 return (unsigned long)sys_call_table[nr]; 514 return (unsigned long)sys_call_table[nr];
515} 515}
516 516
517static int __init init_ftrace_syscalls(void) 517void __init init_ftrace_syscalls(void)
518{ 518{
519 struct syscall_metadata *meta; 519 struct syscall_metadata *meta;
520 unsigned long addr; 520 unsigned long addr;
@@ -524,7 +524,7 @@ static int __init init_ftrace_syscalls(void)
524 GFP_KERNEL); 524 GFP_KERNEL);
525 if (!syscalls_metadata) { 525 if (!syscalls_metadata) {
526 WARN_ON(1); 526 WARN_ON(1);
527 return -ENOMEM; 527 return;
528 } 528 }
529 529
530 for (i = 0; i < NR_syscalls; i++) { 530 for (i = 0; i < NR_syscalls; i++) {
@@ -536,10 +536,7 @@ static int __init init_ftrace_syscalls(void)
536 meta->syscall_nr = i; 536 meta->syscall_nr = i;
537 syscalls_metadata[i] = meta; 537 syscalls_metadata[i] = meta;
538 } 538 }
539
540 return 0;
541} 539}
542early_initcall(init_ftrace_syscalls);
543 540
544#ifdef CONFIG_PERF_EVENTS 541#ifdef CONFIG_PERF_EVENTS
545 542