12 #include <linux/module.h>
26 static int wakeup_cpu;
27 static int wakeup_current_cpu;
28 static unsigned wakeup_prio = -1;
39 static int save_lat_flag;
41 #define TRACE_DISPLAY_GRAPH 1
44 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
56 #define is_graph() (tracer_flags.val & TRACE_DISPLAY_GRAPH)
58 #ifdef CONFIG_FUNCTION_TRACER
89 if (cpu != wakeup_current_cpu)
111 wakeup_tracer_call(
unsigned long ip,
unsigned long parent_ip,
119 if (!func_prolog_preempt_disable(tr, &data, &pc))
132 .func = wakeup_tracer_call,
133 .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
137 static int start_func_tracer(
int graph)
144 ret = register_ftrace_graph(&wakeup_graph_return,
145 &wakeup_graph_entry);
155 static void stop_func_tracer(
int graph)
162 unregister_ftrace_graph();
165 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
166 static int wakeup_set_flag(
u32 old_flags,
u32 bit,
int set)
175 stop_func_tracer(!
set);
177 wakeup_reset(wakeup_trace);
178 tracing_max_latency = 0;
180 return start_func_tracer(
set);
190 if (!func_prolog_preempt_disable(tr, &data, &pc))
208 if (!func_prolog_preempt_disable(tr, &data, &pc))
231 #define GRAPH_TRACER_FLAGS (TRACE_GRAPH_PRINT_PROC | \
232 TRACE_GRAPH_PRINT_ABS_TIME | \
233 TRACE_GRAPH_PRINT_DURATION)
247 static void wakeup_print_header(
struct seq_file *
s)
257 unsigned long ip,
unsigned long parent_ip,
258 unsigned long flags,
int pc)
266 #define __trace_function trace_function
268 static int wakeup_set_flag(
u32 old_flags,
u32 bit,
int set)
287 #ifdef CONFIG_FUNCTION_TRACER
288 static void wakeup_print_header(
struct seq_file *s)
293 static void wakeup_print_header(
struct seq_file *s)
309 if (delta <= tracing_max_latency)
318 if (task != wakeup_task)
321 wakeup_current_cpu =
cpu;
325 probe_wakeup_sched_switch(
void *ignore,
349 if (next != wakeup_task)
357 if (
likely(disabled != 1))
364 if (
unlikely(!tracer_enabled || next != wakeup_task))
368 data = wakeup_trace->
data[wakeup_cpu];
377 if (!report_latency(delta))
381 tracing_max_latency =
delta;
382 update_max_tr(wakeup_trace, wakeup_task, wakeup_cpu);
386 __wakeup_reset(wakeup_trace);
399 put_task_struct(wakeup_task);
418 probe_wakeup(
void *ignore,
struct task_struct *
p,
int success)
426 if (
likely(!tracer_enabled))
432 if ((wakeup_rt && !rt_task(p)) ||
433 p->
prio >= wakeup_prio ||
446 if (!tracer_enabled || p->
prio >= wakeup_prio)
450 __wakeup_reset(wakeup_trace);
452 wakeup_cpu = task_cpu(p);
453 wakeup_current_cpu = wakeup_cpu;
454 wakeup_prio = p->
prio;
461 data = wakeup_trace->
data[wakeup_cpu];
478 static void start_wakeup_tracer(
struct trace_array *tr)
482 ret = register_trace_sched_wakeup(probe_wakeup,
NULL);
484 pr_info(
"wakeup trace: Couldn't activate tracepoint"
485 " probe to kernel_sched_wakeup\n");
489 ret = register_trace_sched_wakeup_new(probe_wakeup,
NULL);
491 pr_info(
"wakeup trace: Couldn't activate tracepoint"
492 " probe to kernel_sched_wakeup_new\n");
496 ret = register_trace_sched_switch(probe_wakeup_sched_switch,
NULL);
498 pr_info(
"sched trace: Couldn't activate tracepoint"
499 " probe to kernel_sched_switch\n");
500 goto fail_deprobe_wake_new;
503 ret = register_trace_sched_migrate_task(probe_wakeup_migrate_task,
NULL);
505 pr_info(
"wakeup trace: Couldn't activate tracepoint"
506 " probe to kernel_sched_migrate_task\n");
525 fail_deprobe_wake_new:
526 unregister_trace_sched_wakeup_new(probe_wakeup,
NULL);
528 unregister_trace_sched_wakeup(probe_wakeup,
NULL);
531 static void stop_wakeup_tracer(
struct trace_array *tr)
535 unregister_trace_sched_switch(probe_wakeup_sched_switch,
NULL);
536 unregister_trace_sched_wakeup_new(probe_wakeup,
NULL);
537 unregister_trace_sched_wakeup(probe_wakeup,
NULL);
538 unregister_trace_sched_migrate_task(probe_wakeup_migrate_task,
NULL);
541 static int __wakeup_tracer_init(
struct trace_array *tr)
546 tracing_max_latency = 0;
548 start_wakeup_tracer(tr);
552 static int wakeup_tracer_init(
struct trace_array *tr)
555 return __wakeup_tracer_init(tr);
558 static int wakeup_rt_tracer_init(
struct trace_array *tr)
561 return __wakeup_tracer_init(tr);
564 static void wakeup_tracer_reset(
struct trace_array *tr)
566 stop_wakeup_tracer(tr);
574 static void wakeup_tracer_start(
struct trace_array *tr)
580 static void wakeup_tracer_stop(
struct trace_array *tr)
585 static struct tracer wakeup_tracer __read_mostly =
588 .init = wakeup_tracer_init,
589 .reset = wakeup_tracer_reset,
590 .start = wakeup_tracer_start,
591 .stop = wakeup_tracer_stop,
593 .print_header = wakeup_print_header,
594 .print_line = wakeup_print_line,
595 .flags = &tracer_flags,
596 .set_flag = wakeup_set_flag,
597 #ifdef CONFIG_FTRACE_SELFTEST
598 .selftest = trace_selftest_startup_wakeup,
600 .open = wakeup_trace_open,
601 .close = wakeup_trace_close,
605 static struct tracer wakeup_rt_tracer __read_mostly =
608 .init = wakeup_rt_tracer_init,
609 .reset = wakeup_tracer_reset,
610 .start = wakeup_tracer_start,
611 .stop = wakeup_tracer_stop,
614 .print_header = wakeup_print_header,
615 .print_line = wakeup_print_line,
616 .flags = &tracer_flags,
617 .set_flag = wakeup_set_flag,
618 #ifdef CONFIG_FTRACE_SELFTEST
619 .selftest = trace_selftest_startup_wakeup,
621 .open = wakeup_trace_open,
622 .close = wakeup_trace_close,
626 __init static int init_wakeup_tracer(
void)