Commit e4a3f541f0b67fdad98b326c851dfe7f4b6b6dad
Committed by
Steven Rostedt
1 parent
e08fbb78f0
Exists in
master
and in
4 other branches
tracing: Still trace filtered irq functions when irq trace is disabled
If a function is set to be traced by the set_graph_function, but the option funcgraph-irqs is zero, and the traced function happens to be called from a interrupt, it will not be traced. The point of funcgraph-irqs is to not trace interrupts when we are preempted by an irq, not to not trace functions we want to trace that happen to be *in* a irq. Luckily the current->trace_recursion element is perfect to add a flag to help us be able to trace functions within an interrupt even when we are not tracing interrupts that preempt the trace. Reported-by: Heiko Carstens <heiko.carstens@de.ibm.com> Tested-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Showing 2 changed files with 35 additions and 17 deletions Side-by-side Diff
kernel/trace/trace.h
... | ... | @@ -278,6 +278,29 @@ |
278 | 278 | }; |
279 | 279 | |
280 | 280 | |
281 | +/* Only current can touch trace_recursion */ | |
282 | +#define trace_recursion_inc() do { (current)->trace_recursion++; } while (0) | |
283 | +#define trace_recursion_dec() do { (current)->trace_recursion--; } while (0) | |
284 | + | |
285 | +/* Ring buffer has the 10 LSB bits to count */ | |
286 | +#define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff) | |
287 | + | |
288 | +/* for function tracing recursion */ | |
289 | +#define TRACE_INTERNAL_BIT (1<<11) | |
290 | +#define TRACE_GLOBAL_BIT (1<<12) | |
291 | +/* | |
292 | + * Abuse of the trace_recursion. | |
293 | + * As we need a way to maintain state if we are tracing the function | |
294 | + * graph in irq because we want to trace a particular function that | |
295 | + * was called in irq context but we have irq tracing off. Since this | |
296 | + * can only be modified by current, we can reuse trace_recursion. | |
297 | + */ | |
298 | +#define TRACE_IRQ_BIT (1<<13) | |
299 | + | |
300 | +#define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0) | |
301 | +#define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0) | |
302 | +#define trace_recursion_test(bit) ((current)->trace_recursion & (bit)) | |
303 | + | |
281 | 304 | #define TRACE_PIPE_ALL_CPU -1 |
282 | 305 | |
283 | 306 | int tracer_init(struct tracer *t, struct trace_array *tr); |
284 | 307 | |
... | ... | @@ -516,8 +539,18 @@ |
516 | 539 | return 1; |
517 | 540 | |
518 | 541 | for (i = 0; i < ftrace_graph_count; i++) { |
519 | - if (addr == ftrace_graph_funcs[i]) | |
542 | + if (addr == ftrace_graph_funcs[i]) { | |
543 | + /* | |
544 | + * If no irqs are to be traced, but a set_graph_function | |
545 | + * is set, and called by an interrupt handler, we still | |
546 | + * want to trace it. | |
547 | + */ | |
548 | + if (in_irq()) | |
549 | + trace_recursion_set(TRACE_IRQ_BIT); | |
550 | + else | |
551 | + trace_recursion_clear(TRACE_IRQ_BIT); | |
520 | 552 | return 1; |
553 | + } | |
521 | 554 | } |
522 | 555 | |
523 | 556 | return 0; |
... | ... | @@ -793,21 +826,6 @@ |
793 | 826 | #define FTRACE_ENTRY_DUP(call, struct_name, id, tstruct, print) \ |
794 | 827 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) |
795 | 828 | #include "trace_entries.h" |
796 | - | |
797 | -/* Only current can touch trace_recursion */ | |
798 | -#define trace_recursion_inc() do { (current)->trace_recursion++; } while (0) | |
799 | -#define trace_recursion_dec() do { (current)->trace_recursion--; } while (0) | |
800 | - | |
801 | -/* Ring buffer has the 10 LSB bits to count */ | |
802 | -#define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff) | |
803 | - | |
804 | -/* for function tracing recursion */ | |
805 | -#define TRACE_INTERNAL_BIT (1<<11) | |
806 | -#define TRACE_GLOBAL_BIT (1<<12) | |
807 | - | |
808 | -#define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0) | |
809 | -#define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0) | |
810 | -#define trace_recursion_test(bit) ((current)->trace_recursion & (bit)) | |
811 | 829 | |
812 | 830 | #endif /* _LINUX_KERNEL_TRACE_H */ |
kernel/trace/trace_functions_graph.c