aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_irqsoff.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2008-11-05 16:05:44 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-06 01:51:03 -0500
commit9036990d462e09366f7297a2d1da6582c3e6b1d3 (patch)
treee110393aad12177cb17fa68cb3fefb18ae2f1037 /kernel/trace/trace_irqsoff.c
parent0f04870148ecb825133bc2733f473b1c5773ac0b (diff)
ftrace: restructure tracing start/stop infrastructure
Impact: change where tracing is started up and stopped Currently, when a new tracer is selected via echo'ing a tracer name into the current_tracer file, the startup is only done if tracing_enabled is set to one. If tracing_enabled is changed to zero (by echo'ing 0 into the tracing_enabled file) a full shutdown is performed. The full startup and shutdown of a tracer can be expensive and the user can lose out traces when echo'ing in 0 to the tracing_enabled file, because the process takes too long. There can also be places that the user would like to start and stop the tracer several times and doing the full startup and shutdown of a tracer might be too expensive. This patch performs the full startup and shutdown when a tracer is selected. It also adds a way to do a quick start or stop of a tracer. The quick version is just a flag that prevents the tracing from taking place, but the overhead of the code is still there. For example, the startup of a tracer may enable tracepoints, or enable the function tracer. The stop and start will just set a flag to have the tracer ignore the calls when the tracepoint or function trace is called. The overhead of the tracer may still be present when the tracer is stopped, but no tracing will occur. Setting the tracer to the 'nop' tracer (or any other tracer) will perform the shutdown of the tracer which will disable the tracepoint or disable the function tracer. The tracing_enabled file will simply start or stop tracing. This change is all internal. The end result for the user should be the same as before. If tracing_enabled is not set, no trace will happen. If tracing_enabled is set, then the trace will happen. The tracing_enabled variable is static between tracers. Enabling tracing_enabled and going to another tracer will keep tracing_enabled enabled. Same is true with disabling tracing_enabled. This patch will now provide a fast start/stop method to the users for enabling or disabling tracing. Note: There were two methods to the struct tracer that were never used: The methods start and stop. These were to be used as a hook to the reading of the trace output, but ended up not being necessary. These two methods are now used to enable the start and stop of each tracer, in case the tracer needs to do more than just not write into the buffer. For example, the irqsoff tracer must stop recording max latencies when tracing is stopped. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace/trace_irqsoff.c')
-rw-r--r--kernel/trace/trace_irqsoff.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 9c74071c10e0..a87a20fa3fc6 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -353,15 +353,28 @@ void trace_preempt_off(unsigned long a0, unsigned long a1)
353} 353}
354#endif /* CONFIG_PREEMPT_TRACER */ 354#endif /* CONFIG_PREEMPT_TRACER */
355 355
356/*
357 * save_tracer_enabled is used to save the state of the tracer_enabled
358 * variable when we disable it when we open a trace output file.
359 */
360static int save_tracer_enabled;
361
356static void start_irqsoff_tracer(struct trace_array *tr) 362static void start_irqsoff_tracer(struct trace_array *tr)
357{ 363{
358 register_ftrace_function(&trace_ops); 364 register_ftrace_function(&trace_ops);
359 tracer_enabled = 1; 365 if (tracing_is_enabled()) {
366 tracer_enabled = 1;
367 save_tracer_enabled = 1;
368 } else {
369 tracer_enabled = 0;
370 save_tracer_enabled = 0;
371 }
360} 372}
361 373
362static void stop_irqsoff_tracer(struct trace_array *tr) 374static void stop_irqsoff_tracer(struct trace_array *tr)
363{ 375{
364 tracer_enabled = 0; 376 tracer_enabled = 0;
377 save_tracer_enabled = 0;
365 unregister_ftrace_function(&trace_ops); 378 unregister_ftrace_function(&trace_ops);
366} 379}
367 380
@@ -389,17 +402,29 @@ static void irqsoff_tracer_ctrl_update(struct trace_array *tr)
389 stop_irqsoff_tracer(tr); 402 stop_irqsoff_tracer(tr);
390} 403}
391 404
405static void irqsoff_tracer_start(struct trace_array *tr)
406{
407 irqsoff_tracer_reset(tr);
408 tracer_enabled = 1;
409 save_tracer_enabled = 1;
410}
411
412static void irqsoff_tracer_stop(struct trace_array *tr)
413{
414 tracer_enabled = 0;
415 save_tracer_enabled = 0;
416}
417
392static void irqsoff_tracer_open(struct trace_iterator *iter) 418static void irqsoff_tracer_open(struct trace_iterator *iter)
393{ 419{
394 /* stop the trace while dumping */ 420 /* stop the trace while dumping */
395 if (iter->tr->ctrl) 421 tracer_enabled = 0;
396 stop_irqsoff_tracer(iter->tr);
397} 422}
398 423
399static void irqsoff_tracer_close(struct trace_iterator *iter) 424static void irqsoff_tracer_close(struct trace_iterator *iter)
400{ 425{
401 if (iter->tr->ctrl) 426 /* restart tracing */
402 start_irqsoff_tracer(iter->tr); 427 tracer_enabled = save_tracer_enabled;
403} 428}
404 429
405#ifdef CONFIG_IRQSOFF_TRACER 430#ifdef CONFIG_IRQSOFF_TRACER
@@ -414,6 +439,8 @@ static struct tracer irqsoff_tracer __read_mostly =
414 .name = "irqsoff", 439 .name = "irqsoff",
415 .init = irqsoff_tracer_init, 440 .init = irqsoff_tracer_init,
416 .reset = irqsoff_tracer_reset, 441 .reset = irqsoff_tracer_reset,
442 .start = irqsoff_tracer_start,
443 .stop = irqsoff_tracer_stop,
417 .open = irqsoff_tracer_open, 444 .open = irqsoff_tracer_open,
418 .close = irqsoff_tracer_close, 445 .close = irqsoff_tracer_close,
419 .ctrl_update = irqsoff_tracer_ctrl_update, 446 .ctrl_update = irqsoff_tracer_ctrl_update,
@@ -440,6 +467,8 @@ static struct tracer preemptoff_tracer __read_mostly =
440 .name = "preemptoff", 467 .name = "preemptoff",
441 .init = preemptoff_tracer_init, 468 .init = preemptoff_tracer_init,
442 .reset = irqsoff_tracer_reset, 469 .reset = irqsoff_tracer_reset,
470 .start = irqsoff_tracer_start,
471 .stop = irqsoff_tracer_stop,
443 .open = irqsoff_tracer_open, 472 .open = irqsoff_tracer_open,
444 .close = irqsoff_tracer_close, 473 .close = irqsoff_tracer_close,
445 .ctrl_update = irqsoff_tracer_ctrl_update, 474 .ctrl_update = irqsoff_tracer_ctrl_update,
@@ -468,6 +497,8 @@ static struct tracer preemptirqsoff_tracer __read_mostly =
468 .name = "preemptirqsoff", 497 .name = "preemptirqsoff",
469 .init = preemptirqsoff_tracer_init, 498 .init = preemptirqsoff_tracer_init,
470 .reset = irqsoff_tracer_reset, 499 .reset = irqsoff_tracer_reset,
500 .start = irqsoff_tracer_start,
501 .stop = irqsoff_tracer_stop,
471 .open = irqsoff_tracer_open, 502 .open = irqsoff_tracer_open,
472 .close = irqsoff_tracer_close, 503 .close = irqsoff_tracer_close,
473 .ctrl_update = irqsoff_tracer_ctrl_update, 504 .ctrl_update = irqsoff_tracer_ctrl_update,