aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-02-02 21:38:32 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-03 00:26:12 -0500
commitb2821ae68b14480bfc85ea1629537163310bc5cd (patch)
tree6d4d2e9501be502f765b8615225f5d1fdb22ab9f /kernel/trace/trace.c
parentdc573f9b20c8710105ac35c08ed0fe1da5160ecd (diff)
trace: fix default boot up tracer
Peter Zijlstra started the functionality to start up a default tracing at bootup. This patch finishes the work. Now if you add 'ftrace=<tracer>' to the command line, when that tracer is registered on bootup, that tracer is selected and starts tracing. Note, all selftests for tracers that are registered after this tracer is disabled. This prevents the selftests from disturbing the running tracer, or the running tracer from disturbing the selftest. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2f8ac1f008f5..2c720c79bc60 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -53,6 +53,11 @@ unsigned long __read_mostly tracing_thresh;
53 */ 53 */
54static bool __read_mostly tracing_selftest_running; 54static bool __read_mostly tracing_selftest_running;
55 55
56/*
57 * If a tracer is running, we do not want to run SELFTEST.
58 */
59static bool __read_mostly tracing_selftest_disabled;
60
56/* For tracers that don't implement custom flags */ 61/* For tracers that don't implement custom flags */
57static struct tracer_opt dummy_tracer_opt[] = { 62static struct tracer_opt dummy_tracer_opt[] = {
58 { } 63 { }
@@ -110,14 +115,19 @@ static cpumask_var_t __read_mostly tracing_buffer_mask;
110 */ 115 */
111int ftrace_dump_on_oops; 116int ftrace_dump_on_oops;
112 117
113static int tracing_set_tracer(char *buf); 118static int tracing_set_tracer(const char *buf);
119
120#define BOOTUP_TRACER_SIZE 100
121static char bootup_tracer_buf[BOOTUP_TRACER_SIZE] __initdata;
122static char *default_bootup_tracer;
114 123
115static int __init set_ftrace(char *str) 124static int __init set_ftrace(char *str)
116{ 125{
117 tracing_set_tracer(str); 126 strncpy(bootup_tracer_buf, str, BOOTUP_TRACER_SIZE);
127 default_bootup_tracer = bootup_tracer_buf;
118 return 1; 128 return 1;
119} 129}
120__setup("ftrace", set_ftrace); 130__setup("ftrace=", set_ftrace);
121 131
122static int __init set_ftrace_dump_on_oops(char *str) 132static int __init set_ftrace_dump_on_oops(char *str)
123{ 133{
@@ -468,7 +478,7 @@ int register_tracer(struct tracer *type)
468 type->flags->opts = dummy_tracer_opt; 478 type->flags->opts = dummy_tracer_opt;
469 479
470#ifdef CONFIG_FTRACE_STARTUP_TEST 480#ifdef CONFIG_FTRACE_STARTUP_TEST
471 if (type->selftest) { 481 if (type->selftest && !tracing_selftest_disabled) {
472 struct tracer *saved_tracer = current_trace; 482 struct tracer *saved_tracer = current_trace;
473 struct trace_array *tr = &global_trace; 483 struct trace_array *tr = &global_trace;
474 int i; 484 int i;
@@ -510,8 +520,25 @@ int register_tracer(struct tracer *type)
510 out: 520 out:
511 tracing_selftest_running = false; 521 tracing_selftest_running = false;
512 mutex_unlock(&trace_types_lock); 522 mutex_unlock(&trace_types_lock);
513 lock_kernel();
514 523
524 if (!ret && default_bootup_tracer) {
525 if (!strncmp(default_bootup_tracer, type->name,
526 BOOTUP_TRACER_SIZE)) {
527 printk(KERN_INFO "Starting tracer '%s'\n",
528 type->name);
529 /* Do we want this tracer to start on bootup? */
530 tracing_set_tracer(type->name);
531 default_bootup_tracer = NULL;
532 /* disable other selftests, since this will break it. */
533 tracing_selftest_disabled = 1;
534#ifdef CONFIG_FTRACE_STARTUP_TEST
535 printk(KERN_INFO "Disabling FTRACE selftests due"
536 " to running tracer '%s'\n", type->name);
537#endif
538 }
539 }
540
541 lock_kernel();
515 return ret; 542 return ret;
516} 543}
517 544
@@ -2245,7 +2272,7 @@ tracing_set_trace_read(struct file *filp, char __user *ubuf,
2245 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); 2272 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
2246} 2273}
2247 2274
2248static int tracing_set_tracer(char *buf) 2275static int tracing_set_tracer(const char *buf)
2249{ 2276{
2250 struct trace_array *tr = &global_trace; 2277 struct trace_array *tr = &global_trace;
2251 struct tracer *t; 2278 struct tracer *t;
@@ -3163,5 +3190,26 @@ out_free_buffer_mask:
3163out: 3190out:
3164 return ret; 3191 return ret;
3165} 3192}
3193
3194__init static int clear_boot_tracer(void)
3195{
3196 /*
3197 * The default tracer at boot buffer is an init section.
3198 * This function is called in lateinit. If we did not
3199 * find the boot tracer, then clear it out, to prevent
3200 * later registration from accessing the buffer that is
3201 * about to be freed.
3202 */
3203 if (!default_bootup_tracer)
3204 return 0;
3205
3206 printk(KERN_INFO "ftrace bootup tracer '%s' not registered.\n",
3207 default_bootup_tracer);
3208 default_bootup_tracer = NULL;
3209
3210 return 0;
3211}
3212
3166early_initcall(tracer_alloc_buffers); 3213early_initcall(tracer_alloc_buffers);
3167fs_initcall(tracer_init_debugfs); 3214fs_initcall(tracer_init_debugfs);
3215late_initcall(clear_boot_tracer);