15 #include <linux/module.h>
35 static int save_lat_flag;
37 static void stop_irqsoff_tracer(
struct trace_array *
tr,
int graph);
38 static int start_irqsoff_tracer(
struct trace_array *
tr,
int graph);
40 #ifdef CONFIG_PREEMPT_TRACER
47 # define preempt_trace() (0)
50 #ifdef CONFIG_IRQSOFF_TRACER
58 # define irq_trace() (0)
61 #define TRACE_DISPLAY_GRAPH 1
64 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
76 #define is_graph() (tracer_flags.val & TRACE_DISPLAY_GRAPH)
88 #ifdef CONFIG_FUNCTION_TRACER
104 unsigned long *
flags)
127 if (
likely(disabled == 1))
139 irqsoff_tracer_call(
unsigned long ip,
unsigned long parent_ip,
146 if (!func_prolog_dec(tr, &data, &flags))
154 static struct ftrace_ops trace_ops __read_mostly =
156 .func = irqsoff_tracer_call,
157 .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE,
161 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
162 static int irqsoff_set_flag(
u32 old_flags,
u32 bit,
int set)
172 stop_irqsoff_tracer(irqsoff_trace, !
set);
177 tracing_max_latency = 0;
180 return start_irqsoff_tracer(irqsoff_trace,
set);
191 if (!func_prolog_dec(tr, &data, &flags))
208 if (!func_prolog_dec(tr, &data, &flags))
229 #define GRAPH_TRACER_FLAGS (TRACE_GRAPH_PRINT_CPU | \
230 TRACE_GRAPH_PRINT_PROC | \
231 TRACE_GRAPH_PRINT_ABS_TIME | \
232 TRACE_GRAPH_PRINT_DURATION)
246 static void irqsoff_print_header(
struct seq_file *
s)
256 unsigned long ip,
unsigned long parent_ip,
257 unsigned long flags,
int pc)
266 #define __trace_function trace_function
268 static int irqsoff_set_flag(
u32 old_flags,
u32 bit,
int set)
287 #ifdef CONFIG_FUNCTION_TRACER
288 static void irqsoff_print_header(
struct seq_file *s)
293 static void irqsoff_print_header(
struct seq_file *s)
309 if (delta <= tracing_max_latency)
318 unsigned long parent_ip,
333 if (!report_latency(delta))
339 if (!report_latency(delta))
344 __trace_stack(tr, flags, 5, pc);
352 tracing_max_latency =
delta;
353 update_max_tr_single(tr,
current, cpu);
368 start_critical_timing(
unsigned long ip,
unsigned long parent_ip)
375 if (
likely(!tracer_enabled))
404 stop_critical_timing(
unsigned long ip,
unsigned long parent_ip)
431 check_critical_timing(tr, data, parent_ip ? : ip, cpu);
451 #ifdef CONFIG_IRQSOFF_TRACER
452 #ifdef CONFIG_PROVE_LOCKING
453 void time_hardirqs_on(
unsigned long a0,
unsigned long a1)
456 stop_critical_timing(a0, a1);
459 void time_hardirqs_off(
unsigned long a0,
unsigned long a1)
462 start_critical_timing(a0, a1);
500 void trace_hardirqs_on_caller(
unsigned long caller_addr)
507 void trace_hardirqs_off_caller(
unsigned long caller_addr)
517 #ifdef CONFIG_PREEMPT_TRACER
521 stop_critical_timing(a0, a1);
527 start_critical_timing(a0, a1);
531 static int start_irqsoff_tracer(
struct trace_array *tr,
int graph)
538 ret = register_ftrace_graph(&irqsoff_graph_return,
539 &irqsoff_graph_entry);
549 static void stop_irqsoff_tracer(
struct trace_array *tr,
int graph)
556 unregister_ftrace_graph();
559 static void __irqsoff_tracer_init(
struct trace_array *tr)
564 tracing_max_latency = 0;
570 if (start_irqsoff_tracer(tr,
is_graph()))
574 static void irqsoff_tracer_reset(
struct trace_array *tr)
576 stop_irqsoff_tracer(tr,
is_graph());
582 static void irqsoff_tracer_start(
struct trace_array *tr)
587 static void irqsoff_tracer_stop(
struct trace_array *tr)
592 #ifdef CONFIG_IRQSOFF_TRACER
593 static int irqsoff_tracer_init(
struct trace_array *tr)
597 __irqsoff_tracer_init(tr);
600 static struct tracer irqsoff_tracer __read_mostly =
603 .init = irqsoff_tracer_init,
604 .reset = irqsoff_tracer_reset,
605 .start = irqsoff_tracer_start,
606 .stop = irqsoff_tracer_stop,
608 .print_header = irqsoff_print_header,
609 .print_line = irqsoff_print_line,
610 .flags = &tracer_flags,
611 .set_flag = irqsoff_set_flag,
612 #ifdef CONFIG_FTRACE_SELFTEST
613 .selftest = trace_selftest_startup_irqsoff,
615 .open = irqsoff_trace_open,
616 .close = irqsoff_trace_close,
619 # define register_irqsoff(trace) register_tracer(&trace)
621 # define register_irqsoff(trace) do { } while (0)
624 #ifdef CONFIG_PREEMPT_TRACER
625 static int preemptoff_tracer_init(
struct trace_array *tr)
629 __irqsoff_tracer_init(tr);
633 static struct tracer preemptoff_tracer __read_mostly =
635 .
name =
"preemptoff",
636 .init = preemptoff_tracer_init,
637 .reset = irqsoff_tracer_reset,
638 .start = irqsoff_tracer_start,
639 .stop = irqsoff_tracer_stop,
641 .print_header = irqsoff_print_header,
642 .print_line = irqsoff_print_line,
643 .flags = &tracer_flags,
644 .set_flag = irqsoff_set_flag,
645 #ifdef CONFIG_FTRACE_SELFTEST
646 .selftest = trace_selftest_startup_preemptoff,
648 .open = irqsoff_trace_open,
649 .close = irqsoff_trace_close,
652 # define register_preemptoff(trace) register_tracer(&trace)
654 # define register_preemptoff(trace) do { } while (0)
657 #if defined(CONFIG_IRQSOFF_TRACER) && \
658 defined(CONFIG_PREEMPT_TRACER)
660 static int preemptirqsoff_tracer_init(
struct trace_array *tr)
664 __irqsoff_tracer_init(tr);
668 static struct tracer preemptirqsoff_tracer __read_mostly =
670 .
name =
"preemptirqsoff",
671 .init = preemptirqsoff_tracer_init,
672 .reset = irqsoff_tracer_reset,
673 .start = irqsoff_tracer_start,
674 .stop = irqsoff_tracer_stop,
676 .print_header = irqsoff_print_header,
677 .print_line = irqsoff_print_line,
678 .flags = &tracer_flags,
679 .set_flag = irqsoff_set_flag,
680 #ifdef CONFIG_FTRACE_SELFTEST
681 .selftest = trace_selftest_startup_preemptirqsoff,
683 .open = irqsoff_trace_open,
684 .close = irqsoff_trace_close,
688 # define register_preemptirqsoff(trace) register_tracer(&trace)
690 # define register_preemptirqsoff(trace) do { } while (0)
693 __init static int init_irqsoff_tracer(
void)