aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace.c64
-rw-r--r--kernel/trace/trace.h5
-rw-r--r--kernel/trace/trace_functions.c6
-rw-r--r--kernel/trace/trace_irqsoff.c41
-rw-r--r--kernel/trace/trace_sched_switch.c13
-rw-r--r--kernel/trace/trace_sched_wakeup.c39
6 files changed, 120 insertions, 48 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 113aea9447ec..ff1e9ed9b587 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -150,6 +150,19 @@ static DEFINE_PER_CPU(struct trace_array_cpu, max_data);
150/* tracer_enabled is used to toggle activation of a tracer */ 150/* tracer_enabled is used to toggle activation of a tracer */
151static int tracer_enabled = 1; 151static int tracer_enabled = 1;
152 152
153/**
154 * tracing_is_enabled - return tracer_enabled status
155 *
156 * This function is used by other tracers to know the status
157 * of the tracer_enabled flag. Tracers may use this function
158 * to know if it should enable their features when starting
159 * up. See irqsoff tracer for an example (start_irqsoff_tracer).
160 */
161int tracing_is_enabled(void)
162{
163 return tracer_enabled;
164}
165
153/* function tracing enabled */ 166/* function tracing enabled */
154int ftrace_function_enabled; 167int ftrace_function_enabled;
155 168
@@ -1041,8 +1054,7 @@ void tracing_start_function_trace(void)
1041 trace_ops.func = function_trace_call; 1054 trace_ops.func = function_trace_call;
1042 1055
1043 register_ftrace_function(&trace_ops); 1056 register_ftrace_function(&trace_ops);
1044 if (tracer_enabled) 1057 ftrace_function_enabled = 1;
1045 ftrace_function_enabled = 1;
1046} 1058}
1047 1059
1048void tracing_stop_function_trace(void) 1060void tracing_stop_function_trace(void)
@@ -1189,10 +1201,6 @@ static void *s_start(struct seq_file *m, loff_t *pos)
1189 1201
1190 atomic_inc(&trace_record_cmdline_disabled); 1202 atomic_inc(&trace_record_cmdline_disabled);
1191 1203
1192 /* let the tracer grab locks here if needed */
1193 if (current_trace->start)
1194 current_trace->start(iter);
1195
1196 if (*pos != iter->pos) { 1204 if (*pos != iter->pos) {
1197 iter->ent = NULL; 1205 iter->ent = NULL;
1198 iter->cpu = 0; 1206 iter->cpu = 0;
@@ -1219,14 +1227,7 @@ static void *s_start(struct seq_file *m, loff_t *pos)
1219 1227
1220static void s_stop(struct seq_file *m, void *p) 1228static void s_stop(struct seq_file *m, void *p)
1221{ 1229{
1222 struct trace_iterator *iter = m->private;
1223
1224 atomic_dec(&trace_record_cmdline_disabled); 1230 atomic_dec(&trace_record_cmdline_disabled);
1225
1226 /* let the tracer release locks here if needed */
1227 if (current_trace && current_trace == iter->trace && iter->trace->stop)
1228 iter->trace->stop(iter);
1229
1230 mutex_unlock(&trace_types_lock); 1231 mutex_unlock(&trace_types_lock);
1231} 1232}
1232 1233
@@ -2056,10 +2057,7 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
2056 m->private = iter; 2057 m->private = iter;
2057 2058
2058 /* stop the trace while dumping */ 2059 /* stop the trace while dumping */
2059 if (iter->tr->ctrl) { 2060 tracing_stop();
2060 tracer_enabled = 0;
2061 ftrace_function_enabled = 0;
2062 }
2063 2061
2064 if (iter->trace && iter->trace->open) 2062 if (iter->trace && iter->trace->open)
2065 iter->trace->open(iter); 2063 iter->trace->open(iter);
@@ -2104,14 +2102,7 @@ int tracing_release(struct inode *inode, struct file *file)
2104 iter->trace->close(iter); 2102 iter->trace->close(iter);
2105 2103
2106 /* reenable tracing if it was previously enabled */ 2104 /* reenable tracing if it was previously enabled */
2107 if (iter->tr->ctrl) { 2105 tracing_start();
2108 tracer_enabled = 1;
2109 /*
2110 * It is safe to enable function tracing even if it
2111 * isn't used
2112 */
2113 ftrace_function_enabled = 1;
2114 }
2115 mutex_unlock(&trace_types_lock); 2106 mutex_unlock(&trace_types_lock);
2116 2107
2117 seq_release(inode, file); 2108 seq_release(inode, file);
@@ -2449,11 +2440,10 @@ static ssize_t
2449tracing_ctrl_read(struct file *filp, char __user *ubuf, 2440tracing_ctrl_read(struct file *filp, char __user *ubuf,
2450 size_t cnt, loff_t *ppos) 2441 size_t cnt, loff_t *ppos)
2451{ 2442{
2452 struct trace_array *tr = filp->private_data;
2453 char buf[64]; 2443 char buf[64];
2454 int r; 2444 int r;
2455 2445
2456 r = sprintf(buf, "%ld\n", tr->ctrl); 2446 r = sprintf(buf, "%u\n", tracer_enabled);
2457 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); 2447 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
2458} 2448}
2459 2449
@@ -2481,16 +2471,18 @@ tracing_ctrl_write(struct file *filp, const char __user *ubuf,
2481 val = !!val; 2471 val = !!val;
2482 2472
2483 mutex_lock(&trace_types_lock); 2473 mutex_lock(&trace_types_lock);
2484 if (tr->ctrl ^ val) { 2474 if (tracer_enabled ^ val) {
2485 if (val) 2475 if (val) {
2486 tracer_enabled = 1; 2476 tracer_enabled = 1;
2487 else 2477 if (current_trace->start)
2478 current_trace->start(tr);
2479 tracing_start();
2480 } else {
2488 tracer_enabled = 0; 2481 tracer_enabled = 0;
2489 2482 tracing_stop();
2490 tr->ctrl = val; 2483 if (current_trace->stop)
2491 2484 current_trace->stop(tr);
2492 if (current_trace && current_trace->ctrl_update) 2485 }
2493 current_trace->ctrl_update(tr);
2494 } 2486 }
2495 mutex_unlock(&trace_types_lock); 2487 mutex_unlock(&trace_types_lock);
2496 2488
@@ -3372,7 +3364,7 @@ __init static int tracer_alloc_buffers(void)
3372#endif 3364#endif
3373 3365
3374 /* All seems OK, enable tracing */ 3366 /* All seems OK, enable tracing */
3375 global_trace.ctrl = tracer_enabled; 3367 global_trace.ctrl = 1;
3376 tracing_disabled = 0; 3368 tracing_disabled = 0;
3377 3369
3378 atomic_notifier_chain_register(&panic_notifier_list, 3370 atomic_notifier_chain_register(&panic_notifier_list,
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index cc14a6bc1094..3422489fad5e 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -237,11 +237,11 @@ struct tracer {
237 const char *name; 237 const char *name;
238 void (*init)(struct trace_array *tr); 238 void (*init)(struct trace_array *tr);
239 void (*reset)(struct trace_array *tr); 239 void (*reset)(struct trace_array *tr);
240 void (*start)(struct trace_array *tr);
241 void (*stop)(struct trace_array *tr);
240 void (*open)(struct trace_iterator *iter); 242 void (*open)(struct trace_iterator *iter);
241 void (*pipe_open)(struct trace_iterator *iter); 243 void (*pipe_open)(struct trace_iterator *iter);
242 void (*close)(struct trace_iterator *iter); 244 void (*close)(struct trace_iterator *iter);
243 void (*start)(struct trace_iterator *iter);
244 void (*stop)(struct trace_iterator *iter);
245 ssize_t (*read)(struct trace_iterator *iter, 245 ssize_t (*read)(struct trace_iterator *iter,
246 struct file *filp, char __user *ubuf, 246 struct file *filp, char __user *ubuf,
247 size_t cnt, loff_t *ppos); 247 size_t cnt, loff_t *ppos);
@@ -282,6 +282,7 @@ struct trace_iterator {
282 long idx; 282 long idx;
283}; 283};
284 284
285int tracing_is_enabled(void);
285void trace_wake_up(void); 286void trace_wake_up(void);
286void tracing_reset(struct trace_array *tr, int cpu); 287void tracing_reset(struct trace_array *tr, int cpu);
287int tracing_open_generic(struct inode *inode, struct file *filp); 288int tracing_open_generic(struct inode *inode, struct file *filp);
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 0f85a64003d3..9f1b0de71284 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -62,11 +62,17 @@ static void function_trace_ctrl_update(struct trace_array *tr)
62 stop_function_trace(tr); 62 stop_function_trace(tr);
63} 63}
64 64
65static void function_trace_start(struct trace_array *tr)
66{
67 function_reset(tr);
68}
69
65static struct tracer function_trace __read_mostly = 70static struct tracer function_trace __read_mostly =
66{ 71{
67 .name = "function", 72 .name = "function",
68 .init = function_trace_init, 73 .init = function_trace_init,
69 .reset = function_trace_reset, 74 .reset = function_trace_reset,
75 .start = function_trace_start,
70 .ctrl_update = function_trace_ctrl_update, 76 .ctrl_update = function_trace_ctrl_update,
71#ifdef CONFIG_FTRACE_SELFTEST 77#ifdef CONFIG_FTRACE_SELFTEST
72 .selftest = trace_selftest_startup_function, 78 .selftest = trace_selftest_startup_function,
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,
diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c
index 888944d3409d..91c699be8c87 100644
--- a/kernel/trace/trace_sched_switch.c
+++ b/kernel/trace/trace_sched_switch.c
@@ -186,11 +186,24 @@ static void sched_switch_trace_ctrl_update(struct trace_array *tr)
186 stop_sched_trace(tr); 186 stop_sched_trace(tr);
187} 187}
188 188
189static void sched_switch_trace_start(struct trace_array *tr)
190{
191 sched_switch_reset(tr);
192 tracing_start_sched_switch();
193}
194
195static void sched_switch_trace_stop(struct trace_array *tr)
196{
197 tracing_stop_sched_switch();
198}
199
189struct tracer sched_switch_trace __read_mostly = 200struct tracer sched_switch_trace __read_mostly =
190{ 201{
191 .name = "sched_switch", 202 .name = "sched_switch",
192 .init = sched_switch_trace_init, 203 .init = sched_switch_trace_init,
193 .reset = sched_switch_trace_reset, 204 .reset = sched_switch_trace_reset,
205 .start = sched_switch_trace_start,
206 .stop = sched_switch_trace_stop,
194 .ctrl_update = sched_switch_trace_ctrl_update, 207 .ctrl_update = sched_switch_trace_ctrl_update,
195#ifdef CONFIG_FTRACE_SELFTEST 208#ifdef CONFIG_FTRACE_SELFTEST
196 .selftest = trace_selftest_startup_sched_switch, 209 .selftest = trace_selftest_startup_sched_switch,
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index 7bc4abf6fca8..240577bc8ba5 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -262,6 +262,12 @@ out:
262 atomic_dec(&wakeup_trace->data[cpu]->disabled); 262 atomic_dec(&wakeup_trace->data[cpu]->disabled);
263} 263}
264 264
265/*
266 * save_tracer_enabled is used to save the state of the tracer_enabled
267 * variable when we disable it when we open a trace output file.
268 */
269static int save_tracer_enabled;
270
265static void start_wakeup_tracer(struct trace_array *tr) 271static void start_wakeup_tracer(struct trace_array *tr)
266{ 272{
267 int ret; 273 int ret;
@@ -300,7 +306,13 @@ static void start_wakeup_tracer(struct trace_array *tr)
300 306
301 register_ftrace_function(&trace_ops); 307 register_ftrace_function(&trace_ops);
302 308
303 tracer_enabled = 1; 309 if (tracing_is_enabled()) {
310 tracer_enabled = 1;
311 save_tracer_enabled = 1;
312 } else {
313 tracer_enabled = 0;
314 save_tracer_enabled = 0;
315 }
304 316
305 return; 317 return;
306fail_deprobe_wake_new: 318fail_deprobe_wake_new:
@@ -312,6 +324,7 @@ fail_deprobe:
312static void stop_wakeup_tracer(struct trace_array *tr) 324static void stop_wakeup_tracer(struct trace_array *tr)
313{ 325{
314 tracer_enabled = 0; 326 tracer_enabled = 0;
327 save_tracer_enabled = 0;
315 unregister_ftrace_function(&trace_ops); 328 unregister_ftrace_function(&trace_ops);
316 unregister_trace_sched_switch(probe_wakeup_sched_switch); 329 unregister_trace_sched_switch(probe_wakeup_sched_switch);
317 unregister_trace_sched_wakeup_new(probe_wakeup); 330 unregister_trace_sched_wakeup_new(probe_wakeup);
@@ -343,18 +356,32 @@ static void wakeup_tracer_ctrl_update(struct trace_array *tr)
343 stop_wakeup_tracer(tr); 356 stop_wakeup_tracer(tr);
344} 357}
345 358
359static void wakeup_tracer_start(struct trace_array *tr)
360{
361 wakeup_reset(tr);
362 tracer_enabled = 1;
363 save_tracer_enabled = 1;
364}
365
366static void wakeup_tracer_stop(struct trace_array *tr)
367{
368 tracer_enabled = 0;
369 save_tracer_enabled = 0;
370}
371
346static void wakeup_tracer_open(struct trace_iterator *iter) 372static void wakeup_tracer_open(struct trace_iterator *iter)
347{ 373{
348 /* stop the trace while dumping */ 374 /* stop the trace while dumping */
349 if (iter->tr->ctrl) 375 tracer_enabled = 0;
350 stop_wakeup_tracer(iter->tr);
351} 376}
352 377
353static void wakeup_tracer_close(struct trace_iterator *iter) 378static void wakeup_tracer_close(struct trace_iterator *iter)
354{ 379{
355 /* forget about any processes we were recording */ 380 /* forget about any processes we were recording */
356 if (iter->tr->ctrl) 381 if (save_tracer_enabled) {
357 start_wakeup_tracer(iter->tr); 382 wakeup_reset(iter->tr);
383 tracer_enabled = 1;
384 }
358} 385}
359 386
360static struct tracer wakeup_tracer __read_mostly = 387static struct tracer wakeup_tracer __read_mostly =
@@ -362,6 +389,8 @@ static struct tracer wakeup_tracer __read_mostly =
362 .name = "wakeup", 389 .name = "wakeup",
363 .init = wakeup_tracer_init, 390 .init = wakeup_tracer_init,
364 .reset = wakeup_tracer_reset, 391 .reset = wakeup_tracer_reset,
392 .start = wakeup_tracer_start,
393 .stop = wakeup_tracer_stop,
365 .open = wakeup_tracer_open, 394 .open = wakeup_tracer_open,
366 .close = wakeup_tracer_close, 395 .close = wakeup_tracer_close,
367 .ctrl_update = wakeup_tracer_ctrl_update, 396 .ctrl_update = wakeup_tracer_ctrl_update,