Blame view
kernel/trace/trace_irqsoff.c
15.5 KB
81d68a96a ftrace: trace irq... |
1 |
/* |
73d8b8bc4 tracing: fix typi... |
2 |
* trace irqs off critical timings |
81d68a96a ftrace: trace irq... |
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
* * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com> * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com> * * From code in the latency_tracer, that is: * * Copyright (C) 2004-2006 Ingo Molnar * Copyright (C) 2004 William Lee Irwin III */ #include <linux/kallsyms.h> #include <linux/debugfs.h> #include <linux/uaccess.h> #include <linux/module.h> #include <linux/ftrace.h> #include <linux/fs.h> #include "trace.h" static struct trace_array *irqsoff_trace __read_mostly; static int tracer_enabled __read_mostly; |
6cd8a4bb2 ftrace: trace pre... |
23 |
static DEFINE_PER_CPU(int, tracing_cpu); |
5389f6fad locking, tracing:... |
24 |
static DEFINE_RAW_SPINLOCK(max_trace_lock); |
89b2f9781 ftrace: fix updat... |
25 |
|
6cd8a4bb2 ftrace: trace pre... |
26 27 28 29 30 31 |
enum { TRACER_IRQS_OFF = (1 << 1), TRACER_PREEMPT_OFF = (1 << 2), }; static int trace_type __read_mostly; |
e9d25fe6e tracing: have lat... |
32 |
static int save_lat_flag; |
62b915f10 tracing: Add grap... |
33 34 |
static void stop_irqsoff_tracer(struct trace_array *tr, int graph); static int start_irqsoff_tracer(struct trace_array *tr, int graph); |
6cd8a4bb2 ftrace: trace pre... |
35 |
#ifdef CONFIG_PREEMPT_TRACER |
e309b41dd ftrace: remove no... |
36 |
static inline int |
6cd8a4bb2 ftrace: trace pre... |
37 38 39 40 41 42 43 44 45 |
preempt_trace(void) { return ((trace_type & TRACER_PREEMPT_OFF) && preempt_count()); } #else # define preempt_trace() (0) #endif #ifdef CONFIG_IRQSOFF_TRACER |
e309b41dd ftrace: remove no... |
46 |
static inline int |
6cd8a4bb2 ftrace: trace pre... |
47 48 49 50 51 52 53 54 |
irq_trace(void) { return ((trace_type & TRACER_IRQS_OFF) && irqs_disabled()); } #else # define irq_trace() (0) #endif |
62b915f10 tracing: Add grap... |
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#define TRACE_DISPLAY_GRAPH 1 static struct tracer_opt trace_opts[] = { #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* display latency trace as call graph */ { TRACER_OPT(display-graph, TRACE_DISPLAY_GRAPH) }, #endif { } /* Empty entry */ }; static struct tracer_flags tracer_flags = { .val = 0, .opts = trace_opts, }; #define is_graph() (tracer_flags.val & TRACE_DISPLAY_GRAPH) |
81d68a96a ftrace: trace irq... |
71 72 73 74 75 |
/* * Sequence count - we record it when starting a measurement and * skip the latency if the sequence has changed - some other section * did a maximum and could disturb our measurement with serial console * printouts, etc. Truly coinciding maximum latencies should be rare |
25985edce Fix common misspe... |
76 |
* and what happens together happens separately as well, so this doesn't |
81d68a96a ftrace: trace irq... |
77 78 79 |
* decrease the validity of the maximum found: */ static __cacheline_aligned_in_smp unsigned long max_sequence; |
606576ce8 ftrace: rename FT... |
80 |
#ifdef CONFIG_FUNCTION_TRACER |
81d68a96a ftrace: trace irq... |
81 |
/* |
5e6d2b9cf tracing: Use one ... |
82 83 84 85 86 87 88 89 90 91 92 |
* Prologue for the preempt and irqs off function tracers. * * Returns 1 if it is OK to continue, and data->disabled is * incremented. * 0 if the trace is to be ignored, and data->disabled * is kept the same. * * Note, this function is also used outside this ifdef but * inside the #ifdef of the function graph tracer below. * This is OK, since the function graph tracer is * dependent on the function tracer. |
81d68a96a ftrace: trace irq... |
93 |
*/ |
5e6d2b9cf tracing: Use one ... |
94 95 96 |
static int func_prolog_dec(struct trace_array *tr, struct trace_array_cpu **data, unsigned long *flags) |
81d68a96a ftrace: trace irq... |
97 |
{ |
81d68a96a ftrace: trace irq... |
98 99 |
long disabled; int cpu; |
361943ad0 ftrace: irqs off ... |
100 101 102 103 104 105 106 107 |
/* * Does not matter if we preempt. We test the flags * afterward, to see if irqs are disabled or not. * If we preempt and get a false positive, the flags * test will fail. */ cpu = raw_smp_processor_id(); if (likely(!per_cpu(tracing_cpu, cpu))) |
5e6d2b9cf tracing: Use one ... |
108 |
return 0; |
81d68a96a ftrace: trace irq... |
109 |
|
5e6d2b9cf tracing: Use one ... |
110 |
local_save_flags(*flags); |
361943ad0 ftrace: irqs off ... |
111 |
/* slight chance to get a false positive on tracing_cpu */ |
5e6d2b9cf tracing: Use one ... |
112 113 |
if (!irqs_disabled_flags(*flags)) return 0; |
81d68a96a ftrace: trace irq... |
114 |
|
5e6d2b9cf tracing: Use one ... |
115 116 |
*data = tr->data[cpu]; disabled = atomic_inc_return(&(*data)->disabled); |
81d68a96a ftrace: trace irq... |
117 118 |
if (likely(disabled == 1)) |
5e6d2b9cf tracing: Use one ... |
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
return 1; atomic_dec(&(*data)->disabled); return 0; } /* * irqsoff uses its own tracer function to keep the overhead down: */ static void irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip) { struct trace_array *tr = irqsoff_trace; struct trace_array_cpu *data; unsigned long flags; if (!func_prolog_dec(tr, &data, &flags)) return; trace_function(tr, ip, parent_ip, flags, preempt_count()); |
81d68a96a ftrace: trace irq... |
140 141 142 143 144 145 146 |
atomic_dec(&data->disabled); } static struct ftrace_ops trace_ops __read_mostly = { .func = irqsoff_tracer_call, |
b848914ce ftrace: Implement... |
147 |
.flags = FTRACE_OPS_FL_GLOBAL, |
81d68a96a ftrace: trace irq... |
148 |
}; |
606576ce8 ftrace: rename FT... |
149 |
#endif /* CONFIG_FUNCTION_TRACER */ |
81d68a96a ftrace: trace irq... |
150 |
|
62b915f10 tracing: Add grap... |
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
#ifdef CONFIG_FUNCTION_GRAPH_TRACER static int irqsoff_set_flag(u32 old_flags, u32 bit, int set) { int cpu; if (!(bit & TRACE_DISPLAY_GRAPH)) return -EINVAL; if (!(is_graph() ^ set)) return 0; stop_irqsoff_tracer(irqsoff_trace, !set); for_each_possible_cpu(cpu) per_cpu(tracing_cpu, cpu) = 0; tracing_max_latency = 0; tracing_reset_online_cpus(irqsoff_trace); return start_irqsoff_tracer(irqsoff_trace, set); } static int irqsoff_graph_entry(struct ftrace_graph_ent *trace) { struct trace_array *tr = irqsoff_trace; struct trace_array_cpu *data; unsigned long flags; |
62b915f10 tracing: Add grap... |
178 |
int ret; |
62b915f10 tracing: Add grap... |
179 |
int pc; |
5e6d2b9cf tracing: Use one ... |
180 |
if (!func_prolog_dec(tr, &data, &flags)) |
62b915f10 tracing: Add grap... |
181 |
return 0; |
5e6d2b9cf tracing: Use one ... |
182 183 |
pc = preempt_count(); ret = __trace_graph_entry(tr, trace, flags, pc); |
62b915f10 tracing: Add grap... |
184 |
atomic_dec(&data->disabled); |
5e6d2b9cf tracing: Use one ... |
185 |
|
62b915f10 tracing: Add grap... |
186 187 188 189 190 191 192 193 |
return ret; } static void irqsoff_graph_return(struct ftrace_graph_ret *trace) { struct trace_array *tr = irqsoff_trace; struct trace_array_cpu *data; unsigned long flags; |
62b915f10 tracing: Add grap... |
194 |
int pc; |
5e6d2b9cf tracing: Use one ... |
195 |
if (!func_prolog_dec(tr, &data, &flags)) |
62b915f10 tracing: Add grap... |
196 |
return; |
5e6d2b9cf tracing: Use one ... |
197 198 |
pc = preempt_count(); __trace_graph_return(tr, trace, flags, pc); |
62b915f10 tracing: Add grap... |
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
atomic_dec(&data->disabled); } static void irqsoff_trace_open(struct trace_iterator *iter) { if (is_graph()) graph_trace_open(iter); } static void irqsoff_trace_close(struct trace_iterator *iter) { if (iter->private) graph_trace_close(iter); } #define GRAPH_TRACER_FLAGS (TRACE_GRAPH_PRINT_CPU | \ |
321e68b09 tracing, function... |
216 217 218 |
TRACE_GRAPH_PRINT_PROC | \ TRACE_GRAPH_PRINT_ABS_TIME | \ TRACE_GRAPH_PRINT_DURATION) |
62b915f10 tracing: Add grap... |
219 220 221 |
static enum print_line_t irqsoff_print_line(struct trace_iterator *iter) { |
62b915f10 tracing: Add grap... |
222 223 224 225 226 |
/* * In graph mode call the graph tracer output function, * otherwise go with the TRACE_FN event handler */ if (is_graph()) |
0a772620a tracing: Make gra... |
227 |
return print_graph_function_flags(iter, GRAPH_TRACER_FLAGS); |
62b915f10 tracing: Add grap... |
228 229 230 231 232 233 |
return TRACE_TYPE_UNHANDLED; } static void irqsoff_print_header(struct seq_file *s) { |
0a772620a tracing: Make gra... |
234 235 236 |
if (is_graph()) print_graph_headers_flags(s, GRAPH_TRACER_FLAGS); else |
62b915f10 tracing: Add grap... |
237 238 239 240 |
trace_default_header(s); } static void |
62b915f10 tracing: Add grap... |
241 242 243 244 |
__trace_function(struct trace_array *tr, unsigned long ip, unsigned long parent_ip, unsigned long flags, int pc) { |
0a772620a tracing: Make gra... |
245 246 247 |
if (is_graph()) trace_graph_function(tr, ip, parent_ip, flags, pc); else |
62b915f10 tracing: Add grap... |
248 |
trace_function(tr, ip, parent_ip, flags, pc); |
62b915f10 tracing: Add grap... |
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
} #else #define __trace_function trace_function static int irqsoff_set_flag(u32 old_flags, u32 bit, int set) { return -EINVAL; } static int irqsoff_graph_entry(struct ftrace_graph_ent *trace) { return -1; } static enum print_line_t irqsoff_print_line(struct trace_iterator *iter) { return TRACE_TYPE_UNHANDLED; } static void irqsoff_graph_return(struct ftrace_graph_ret *trace) { } |
62b915f10 tracing: Add grap... |
270 271 |
static void irqsoff_trace_open(struct trace_iterator *iter) { } static void irqsoff_trace_close(struct trace_iterator *iter) { } |
7e9a49ef5 tracing/latency: ... |
272 273 274 275 276 277 278 279 280 281 282 283 |
#ifdef CONFIG_FUNCTION_TRACER static void irqsoff_print_header(struct seq_file *s) { trace_default_header(s); } #else static void irqsoff_print_header(struct seq_file *s) { trace_latency_header(s); } #endif /* CONFIG_FUNCTION_TRACER */ |
62b915f10 tracing: Add grap... |
284 |
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
81d68a96a ftrace: trace irq... |
285 286 287 |
/* * Should this new latency be reported/recorded? */ |
e309b41dd ftrace: remove no... |
288 |
static int report_latency(cycle_t delta) |
81d68a96a ftrace: trace irq... |
289 290 291 292 293 294 295 296 297 298 |
{ if (tracing_thresh) { if (delta < tracing_thresh) return 0; } else { if (delta <= tracing_max_latency) return 0; } return 1; } |
e309b41dd ftrace: remove no... |
299 |
static void |
81d68a96a ftrace: trace irq... |
300 301 302 303 304 |
check_critical_timing(struct trace_array *tr, struct trace_array_cpu *data, unsigned long parent_ip, int cpu) { |
89b2f9781 ftrace: fix updat... |
305 |
cycle_t T0, T1, delta; |
81d68a96a ftrace: trace irq... |
306 |
unsigned long flags; |
38697053f ftrace: preempt d... |
307 |
int pc; |
81d68a96a ftrace: trace irq... |
308 |
|
81d68a96a ftrace: trace irq... |
309 |
T0 = data->preempt_timestamp; |
750ed1a40 ftrace: timestamp... |
310 |
T1 = ftrace_now(cpu); |
81d68a96a ftrace: trace irq... |
311 312 313 |
delta = T1-T0; local_save_flags(flags); |
6450c1d32 ftrace: move pc c... |
314 |
pc = preempt_count(); |
81d68a96a ftrace: trace irq... |
315 316 |
if (!report_latency(delta)) goto out; |
5389f6fad locking, tracing:... |
317 |
raw_spin_lock_irqsave(&max_trace_lock, flags); |
81d68a96a ftrace: trace irq... |
318 |
|
89b2f9781 ftrace: fix updat... |
319 320 321 |
/* check if we are still the max latency */ if (!report_latency(delta)) goto out_unlock; |
62b915f10 tracing: Add grap... |
322 |
__trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc); |
cc51a0fca tracing: Add stac... |
323 324 |
/* Skip 5 functions to get to the irq/preempt enable function */ __trace_stack(tr, flags, 5, pc); |
81d68a96a ftrace: trace irq... |
325 |
|
81d68a96a ftrace: trace irq... |
326 |
if (data->critical_sequence != max_sequence) |
89b2f9781 ftrace: fix updat... |
327 |
goto out_unlock; |
81d68a96a ftrace: trace irq... |
328 |
|
81d68a96a ftrace: trace irq... |
329 |
data->critical_end = parent_ip; |
b5130b1e7 tracing: do not u... |
330 331 332 333 |
if (likely(!is_tracing_stopped())) { tracing_max_latency = delta; update_max_tr_single(tr, current, cpu); } |
81d68a96a ftrace: trace irq... |
334 |
|
81d68a96a ftrace: trace irq... |
335 |
max_sequence++; |
89b2f9781 ftrace: fix updat... |
336 |
out_unlock: |
5389f6fad locking, tracing:... |
337 |
raw_spin_unlock_irqrestore(&max_trace_lock, flags); |
89b2f9781 ftrace: fix updat... |
338 |
|
81d68a96a ftrace: trace irq... |
339 340 |
out: data->critical_sequence = max_sequence; |
750ed1a40 ftrace: timestamp... |
341 |
data->preempt_timestamp = ftrace_now(cpu); |
62b915f10 tracing: Add grap... |
342 |
__trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc); |
81d68a96a ftrace: trace irq... |
343 |
} |
e309b41dd ftrace: remove no... |
344 |
static inline void |
81d68a96a ftrace: trace irq... |
345 346 347 348 349 350 351 352 353 |
start_critical_timing(unsigned long ip, unsigned long parent_ip) { int cpu; struct trace_array *tr = irqsoff_trace; struct trace_array_cpu *data; unsigned long flags; if (likely(!tracer_enabled)) return; |
c5f888cae ftrace: irqsoff u... |
354 355 356 |
cpu = raw_smp_processor_id(); if (per_cpu(tracing_cpu, cpu)) |
6cd8a4bb2 ftrace: trace pre... |
357 |
return; |
81d68a96a ftrace: trace irq... |
358 |
data = tr->data[cpu]; |
c5f888cae ftrace: irqsoff u... |
359 |
if (unlikely(!data) || atomic_read(&data->disabled)) |
81d68a96a ftrace: trace irq... |
360 361 362 363 364 |
return; atomic_inc(&data->disabled); data->critical_sequence = max_sequence; |
750ed1a40 ftrace: timestamp... |
365 |
data->preempt_timestamp = ftrace_now(cpu); |
6cd8a4bb2 ftrace: trace pre... |
366 |
data->critical_start = parent_ip ? : ip; |
81d68a96a ftrace: trace irq... |
367 368 |
local_save_flags(flags); |
6cd8a4bb2 ftrace: trace pre... |
369 |
|
62b915f10 tracing: Add grap... |
370 |
__trace_function(tr, ip, parent_ip, flags, preempt_count()); |
81d68a96a ftrace: trace irq... |
371 |
|
c5f888cae ftrace: irqsoff u... |
372 |
per_cpu(tracing_cpu, cpu) = 1; |
6cd8a4bb2 ftrace: trace pre... |
373 |
|
81d68a96a ftrace: trace irq... |
374 375 |
atomic_dec(&data->disabled); } |
e309b41dd ftrace: remove no... |
376 |
static inline void |
81d68a96a ftrace: trace irq... |
377 378 379 380 381 382 |
stop_critical_timing(unsigned long ip, unsigned long parent_ip) { int cpu; struct trace_array *tr = irqsoff_trace; struct trace_array_cpu *data; unsigned long flags; |
c5f888cae ftrace: irqsoff u... |
383 |
cpu = raw_smp_processor_id(); |
6cd8a4bb2 ftrace: trace pre... |
384 |
/* Always clear the tracing cpu on stopping the trace */ |
c5f888cae ftrace: irqsoff u... |
385 386 |
if (unlikely(per_cpu(tracing_cpu, cpu))) per_cpu(tracing_cpu, cpu) = 0; |
6cd8a4bb2 ftrace: trace pre... |
387 388 389 390 |
else return; if (!tracer_enabled) |
81d68a96a ftrace: trace irq... |
391 |
return; |
81d68a96a ftrace: trace irq... |
392 |
data = tr->data[cpu]; |
3928a8a2d ftrace: make work... |
393 |
if (unlikely(!data) || |
81d68a96a ftrace: trace irq... |
394 395 396 397 |
!data->critical_start || atomic_read(&data->disabled)) return; atomic_inc(&data->disabled); |
c5f888cae ftrace: irqsoff u... |
398 |
|
81d68a96a ftrace: trace irq... |
399 |
local_save_flags(flags); |
62b915f10 tracing: Add grap... |
400 |
__trace_function(tr, ip, parent_ip, flags, preempt_count()); |
6cd8a4bb2 ftrace: trace pre... |
401 |
check_critical_timing(tr, data, parent_ip ? : ip, cpu); |
81d68a96a ftrace: trace irq... |
402 403 404 |
data->critical_start = 0; atomic_dec(&data->disabled); } |
6cd8a4bb2 ftrace: trace pre... |
405 |
/* start and stop critical timings used to for stoppage (in idle) */ |
e309b41dd ftrace: remove no... |
406 |
void start_critical_timings(void) |
81d68a96a ftrace: trace irq... |
407 |
{ |
6cd8a4bb2 ftrace: trace pre... |
408 |
if (preempt_trace() || irq_trace()) |
81d68a96a ftrace: trace irq... |
409 410 |
start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } |
1fe371044 ftrace: fix modul... |
411 |
EXPORT_SYMBOL_GPL(start_critical_timings); |
81d68a96a ftrace: trace irq... |
412 |
|
e309b41dd ftrace: remove no... |
413 |
void stop_critical_timings(void) |
81d68a96a ftrace: trace irq... |
414 |
{ |
6cd8a4bb2 ftrace: trace pre... |
415 |
if (preempt_trace() || irq_trace()) |
81d68a96a ftrace: trace irq... |
416 417 |
stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } |
1fe371044 ftrace: fix modul... |
418 |
EXPORT_SYMBOL_GPL(stop_critical_timings); |
81d68a96a ftrace: trace irq... |
419 |
|
6cd8a4bb2 ftrace: trace pre... |
420 |
#ifdef CONFIG_IRQSOFF_TRACER |
81d68a96a ftrace: trace irq... |
421 |
#ifdef CONFIG_PROVE_LOCKING |
e309b41dd ftrace: remove no... |
422 |
void time_hardirqs_on(unsigned long a0, unsigned long a1) |
81d68a96a ftrace: trace irq... |
423 |
{ |
6cd8a4bb2 ftrace: trace pre... |
424 |
if (!preempt_trace() && irq_trace()) |
81d68a96a ftrace: trace irq... |
425 426 |
stop_critical_timing(a0, a1); } |
e309b41dd ftrace: remove no... |
427 |
void time_hardirqs_off(unsigned long a0, unsigned long a1) |
81d68a96a ftrace: trace irq... |
428 |
{ |
6cd8a4bb2 ftrace: trace pre... |
429 |
if (!preempt_trace() && irq_trace()) |
81d68a96a ftrace: trace irq... |
430 431 432 433 434 435 436 437 |
start_critical_timing(a0, a1); } #else /* !CONFIG_PROVE_LOCKING */ /* * Stubs: */ |
81d68a96a ftrace: trace irq... |
438 439 440 441 442 443 444 |
void trace_softirqs_on(unsigned long ip) { } void trace_softirqs_off(unsigned long ip) { } |
e309b41dd ftrace: remove no... |
445 |
inline void print_irqtrace_events(struct task_struct *curr) |
81d68a96a ftrace: trace irq... |
446 447 448 449 450 451 |
{ } /* * We are only interested in hardirq on/off events: */ |
e309b41dd ftrace: remove no... |
452 |
void trace_hardirqs_on(void) |
81d68a96a ftrace: trace irq... |
453 |
{ |
6cd8a4bb2 ftrace: trace pre... |
454 |
if (!preempt_trace() && irq_trace()) |
81d68a96a ftrace: trace irq... |
455 456 457 |
stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } EXPORT_SYMBOL(trace_hardirqs_on); |
e309b41dd ftrace: remove no... |
458 |
void trace_hardirqs_off(void) |
81d68a96a ftrace: trace irq... |
459 |
{ |
6cd8a4bb2 ftrace: trace pre... |
460 |
if (!preempt_trace() && irq_trace()) |
81d68a96a ftrace: trace irq... |
461 462 463 |
start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); } EXPORT_SYMBOL(trace_hardirqs_off); |
e309b41dd ftrace: remove no... |
464 |
void trace_hardirqs_on_caller(unsigned long caller_addr) |
81d68a96a ftrace: trace irq... |
465 |
{ |
6cd8a4bb2 ftrace: trace pre... |
466 |
if (!preempt_trace() && irq_trace()) |
81d68a96a ftrace: trace irq... |
467 468 469 |
stop_critical_timing(CALLER_ADDR0, caller_addr); } EXPORT_SYMBOL(trace_hardirqs_on_caller); |
e309b41dd ftrace: remove no... |
470 |
void trace_hardirqs_off_caller(unsigned long caller_addr) |
81d68a96a ftrace: trace irq... |
471 |
{ |
6cd8a4bb2 ftrace: trace pre... |
472 |
if (!preempt_trace() && irq_trace()) |
81d68a96a ftrace: trace irq... |
473 474 475 476 477 |
start_critical_timing(CALLER_ADDR0, caller_addr); } EXPORT_SYMBOL(trace_hardirqs_off_caller); #endif /* CONFIG_PROVE_LOCKING */ |
6cd8a4bb2 ftrace: trace pre... |
478 479 480 |
#endif /* CONFIG_IRQSOFF_TRACER */ #ifdef CONFIG_PREEMPT_TRACER |
e309b41dd ftrace: remove no... |
481 |
void trace_preempt_on(unsigned long a0, unsigned long a1) |
6cd8a4bb2 ftrace: trace pre... |
482 |
{ |
e36de1de4 tracing: Fix pree... |
483 |
if (preempt_trace() && !irq_trace()) |
1e01cb0c6 ftrace: only trac... |
484 |
stop_critical_timing(a0, a1); |
6cd8a4bb2 ftrace: trace pre... |
485 |
} |
e309b41dd ftrace: remove no... |
486 |
void trace_preempt_off(unsigned long a0, unsigned long a1) |
6cd8a4bb2 ftrace: trace pre... |
487 |
{ |
e36de1de4 tracing: Fix pree... |
488 |
if (preempt_trace() && !irq_trace()) |
1e01cb0c6 ftrace: only trac... |
489 |
start_critical_timing(a0, a1); |
6cd8a4bb2 ftrace: trace pre... |
490 491 |
} #endif /* CONFIG_PREEMPT_TRACER */ |
81d68a96a ftrace: trace irq... |
492 |
|
62b915f10 tracing: Add grap... |
493 |
static int start_irqsoff_tracer(struct trace_array *tr, int graph) |
81d68a96a ftrace: trace irq... |
494 |
{ |
62b915f10 tracing: Add grap... |
495 496 497 498 499 500 501 502 503 |
int ret = 0; if (!graph) ret = register_ftrace_function(&trace_ops); else ret = register_ftrace_graph(&irqsoff_graph_return, &irqsoff_graph_entry); if (!ret && tracing_is_enabled()) |
9036990d4 ftrace: restructu... |
504 |
tracer_enabled = 1; |
94523e818 trace: remove int... |
505 |
else |
9036990d4 ftrace: restructu... |
506 |
tracer_enabled = 0; |
62b915f10 tracing: Add grap... |
507 508 |
return ret; |
81d68a96a ftrace: trace irq... |
509 |
} |
62b915f10 tracing: Add grap... |
510 |
static void stop_irqsoff_tracer(struct trace_array *tr, int graph) |
81d68a96a ftrace: trace irq... |
511 |
{ |
81d68a96a ftrace: trace irq... |
512 |
tracer_enabled = 0; |
62b915f10 tracing: Add grap... |
513 514 515 516 517 |
if (!graph) unregister_ftrace_function(&trace_ops); else unregister_ftrace_graph(); |
81d68a96a ftrace: trace irq... |
518 |
} |
6cd8a4bb2 ftrace: trace pre... |
519 |
static void __irqsoff_tracer_init(struct trace_array *tr) |
81d68a96a ftrace: trace irq... |
520 |
{ |
e9d25fe6e tracing: have lat... |
521 522 |
save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT; trace_flags |= TRACE_ITER_LATENCY_FMT; |
745b1626d trace: set max la... |
523 |
tracing_max_latency = 0; |
81d68a96a ftrace: trace irq... |
524 |
irqsoff_trace = tr; |
c5f888cae ftrace: irqsoff u... |
525 |
/* make sure that the tracer is visible */ |
81d68a96a ftrace: trace irq... |
526 |
smp_wmb(); |
2f26ebd54 tracing: use time... |
527 |
tracing_reset_online_cpus(tr); |
62b915f10 tracing: Add grap... |
528 529 530 531 |
if (start_irqsoff_tracer(tr, is_graph())) printk(KERN_ERR "failed to start irqsoff tracer "); |
81d68a96a ftrace: trace irq... |
532 533 534 535 |
} static void irqsoff_tracer_reset(struct trace_array *tr) { |
62b915f10 tracing: Add grap... |
536 |
stop_irqsoff_tracer(tr, is_graph()); |
e9d25fe6e tracing: have lat... |
537 538 539 |
if (!save_lat_flag) trace_flags &= ~TRACE_ITER_LATENCY_FMT; |
81d68a96a ftrace: trace irq... |
540 |
} |
9036990d4 ftrace: restructu... |
541 542 |
static void irqsoff_tracer_start(struct trace_array *tr) { |
9036990d4 ftrace: restructu... |
543 |
tracer_enabled = 1; |
9036990d4 ftrace: restructu... |
544 545 546 547 548 |
} static void irqsoff_tracer_stop(struct trace_array *tr) { tracer_enabled = 0; |
81d68a96a ftrace: trace irq... |
549 |
} |
6cd8a4bb2 ftrace: trace pre... |
550 |
#ifdef CONFIG_IRQSOFF_TRACER |
1c80025a4 tracing/ftrace: c... |
551 |
static int irqsoff_tracer_init(struct trace_array *tr) |
6cd8a4bb2 ftrace: trace pre... |
552 553 554 555 |
{ trace_type = TRACER_IRQS_OFF; __irqsoff_tracer_init(tr); |
1c80025a4 tracing/ftrace: c... |
556 |
return 0; |
6cd8a4bb2 ftrace: trace pre... |
557 |
} |
81d68a96a ftrace: trace irq... |
558 559 560 561 562 |
static struct tracer irqsoff_tracer __read_mostly = { .name = "irqsoff", .init = irqsoff_tracer_init, .reset = irqsoff_tracer_reset, |
9036990d4 ftrace: restructu... |
563 564 |
.start = irqsoff_tracer_start, .stop = irqsoff_tracer_stop, |
81d68a96a ftrace: trace irq... |
565 |
.print_max = 1, |
62b915f10 tracing: Add grap... |
566 567 568 569 |
.print_header = irqsoff_print_header, .print_line = irqsoff_print_line, .flags = &tracer_flags, .set_flag = irqsoff_set_flag, |
60a11774b ftrace: add self-... |
570 571 572 |
#ifdef CONFIG_FTRACE_SELFTEST .selftest = trace_selftest_startup_irqsoff, #endif |
62b915f10 tracing: Add grap... |
573 574 |
.open = irqsoff_trace_open, .close = irqsoff_trace_close, |
ef710e100 tracing: Shrink m... |
575 |
.use_max_tr = 1, |
81d68a96a ftrace: trace irq... |
576 |
}; |
6cd8a4bb2 ftrace: trace pre... |
577 578 579 580 581 582 |
# define register_irqsoff(trace) register_tracer(&trace) #else # define register_irqsoff(trace) do { } while (0) #endif #ifdef CONFIG_PREEMPT_TRACER |
1c80025a4 tracing/ftrace: c... |
583 |
static int preemptoff_tracer_init(struct trace_array *tr) |
6cd8a4bb2 ftrace: trace pre... |
584 585 586 587 |
{ trace_type = TRACER_PREEMPT_OFF; __irqsoff_tracer_init(tr); |
1c80025a4 tracing/ftrace: c... |
588 |
return 0; |
6cd8a4bb2 ftrace: trace pre... |
589 590 591 592 593 594 595 |
} static struct tracer preemptoff_tracer __read_mostly = { .name = "preemptoff", .init = preemptoff_tracer_init, .reset = irqsoff_tracer_reset, |
9036990d4 ftrace: restructu... |
596 597 |
.start = irqsoff_tracer_start, .stop = irqsoff_tracer_stop, |
6cd8a4bb2 ftrace: trace pre... |
598 |
.print_max = 1, |
62b915f10 tracing: Add grap... |
599 600 601 602 |
.print_header = irqsoff_print_header, .print_line = irqsoff_print_line, .flags = &tracer_flags, .set_flag = irqsoff_set_flag, |
60a11774b ftrace: add self-... |
603 604 605 |
#ifdef CONFIG_FTRACE_SELFTEST .selftest = trace_selftest_startup_preemptoff, #endif |
62b915f10 tracing: Add grap... |
606 607 |
.open = irqsoff_trace_open, .close = irqsoff_trace_close, |
ef710e100 tracing: Shrink m... |
608 |
.use_max_tr = 1, |
6cd8a4bb2 ftrace: trace pre... |
609 610 611 612 613 614 615 616 |
}; # define register_preemptoff(trace) register_tracer(&trace) #else # define register_preemptoff(trace) do { } while (0) #endif #if defined(CONFIG_IRQSOFF_TRACER) && \ defined(CONFIG_PREEMPT_TRACER) |
1c80025a4 tracing/ftrace: c... |
617 |
static int preemptirqsoff_tracer_init(struct trace_array *tr) |
6cd8a4bb2 ftrace: trace pre... |
618 619 620 621 |
{ trace_type = TRACER_IRQS_OFF | TRACER_PREEMPT_OFF; __irqsoff_tracer_init(tr); |
1c80025a4 tracing/ftrace: c... |
622 |
return 0; |
6cd8a4bb2 ftrace: trace pre... |
623 624 625 626 627 628 629 |
} static struct tracer preemptirqsoff_tracer __read_mostly = { .name = "preemptirqsoff", .init = preemptirqsoff_tracer_init, .reset = irqsoff_tracer_reset, |
9036990d4 ftrace: restructu... |
630 631 |
.start = irqsoff_tracer_start, .stop = irqsoff_tracer_stop, |
6cd8a4bb2 ftrace: trace pre... |
632 |
.print_max = 1, |
62b915f10 tracing: Add grap... |
633 634 635 636 |
.print_header = irqsoff_print_header, .print_line = irqsoff_print_line, .flags = &tracer_flags, .set_flag = irqsoff_set_flag, |
60a11774b ftrace: add self-... |
637 638 639 |
#ifdef CONFIG_FTRACE_SELFTEST .selftest = trace_selftest_startup_preemptirqsoff, #endif |
62b915f10 tracing: Add grap... |
640 641 |
.open = irqsoff_trace_open, .close = irqsoff_trace_close, |
ef710e100 tracing: Shrink m... |
642 |
.use_max_tr = 1, |
6cd8a4bb2 ftrace: trace pre... |
643 644 645 646 647 648 |
}; # define register_preemptirqsoff(trace) register_tracer(&trace) #else # define register_preemptirqsoff(trace) do { } while (0) #endif |
81d68a96a ftrace: trace irq... |
649 650 651 |
__init static int init_irqsoff_tracer(void) { |
6cd8a4bb2 ftrace: trace pre... |
652 653 654 |
register_irqsoff(irqsoff_tracer); register_preemptoff(preemptoff_tracer); register_preemptirqsoff(preemptirqsoff_tracer); |
81d68a96a ftrace: trace irq... |
655 656 657 658 |
return 0; } device_initcall(init_irqsoff_tracer); |