lkml.org 
[lkml]   [2011]   [Jul]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 01/20] tracing: Still trace filtered irq functions when irq trace is
    From: Steven Rostedt <srostedt@redhat.com>

    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>
    ---
    kernel/trace/trace.h | 50 +++++++++++++++++++++++-----------
    kernel/trace/trace_functions_graph.c | 2 +-
    2 files changed, 35 insertions(+), 17 deletions(-)

    diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
    index a3e2db7..651f35b 100644
    --- a/kernel/trace/trace.h
    +++ b/kernel/trace/trace.h
    @@ -278,6 +278,29 @@ struct tracer {
    };


    +/* Only current can touch trace_recursion */
    +#define trace_recursion_inc() do { (current)->trace_recursion++; } while (0)
    +#define trace_recursion_dec() do { (current)->trace_recursion--; } while (0)
    +
    +/* Ring buffer has the 10 LSB bits to count */
    +#define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff)
    +
    +/* for function tracing recursion */
    +#define TRACE_INTERNAL_BIT (1<<11)
    +#define TRACE_GLOBAL_BIT (1<<12)
    +/*
    + * Abuse of the trace_recursion.
    + * As we need a way to maintain state if we are tracing the function
    + * graph in irq because we want to trace a particular function that
    + * was called in irq context but we have irq tracing off. Since this
    + * can only be modified by current, we can reuse trace_recursion.
    + */
    +#define TRACE_IRQ_BIT (1<<13)
    +
    +#define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0)
    +#define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0)
    +#define trace_recursion_test(bit) ((current)->trace_recursion & (bit))
    +
    #define TRACE_PIPE_ALL_CPU -1

    int tracer_init(struct tracer *t, struct trace_array *tr);
    @@ -516,8 +539,18 @@ static inline int ftrace_graph_addr(unsigned long addr)
    return 1;

    for (i = 0; i < ftrace_graph_count; i++) {
    - if (addr == ftrace_graph_funcs[i])
    + if (addr == ftrace_graph_funcs[i]) {
    + /*
    + * If no irqs are to be traced, but a set_graph_function
    + * is set, and called by an interrupt handler, we still
    + * want to trace it.
    + */
    + if (in_irq())
    + trace_recursion_set(TRACE_IRQ_BIT);
    + else
    + trace_recursion_clear(TRACE_IRQ_BIT);
    return 1;
    + }
    }

    return 0;
    @@ -794,19 +827,4 @@ extern const char *__stop___trace_bprintk_fmt[];
    FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print))
    #include "trace_entries.h"

    -/* Only current can touch trace_recursion */
    -#define trace_recursion_inc() do { (current)->trace_recursion++; } while (0)
    -#define trace_recursion_dec() do { (current)->trace_recursion--; } while (0)
    -
    -/* Ring buffer has the 10 LSB bits to count */
    -#define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff)
    -
    -/* for function tracing recursion */
    -#define TRACE_INTERNAL_BIT (1<<11)
    -#define TRACE_GLOBAL_BIT (1<<12)
    -
    -#define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0)
    -#define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0)
    -#define trace_recursion_test(bit) ((current)->trace_recursion & (bit))
    -
    #endif /* _LINUX_KERNEL_TRACE_H */
    diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
    index e8d6bb5..a7d2a4c 100644
    --- a/kernel/trace/trace_functions_graph.c
    +++ b/kernel/trace/trace_functions_graph.c
    @@ -227,7 +227,7 @@ int __trace_graph_entry(struct trace_array *tr,

    static inline int ftrace_graph_ignore_irqs(void)
    {
    - if (!ftrace_graph_skip_irqs)
    + if (!ftrace_graph_skip_irqs || trace_recursion_test(TRACE_IRQ_BIT))
    return 0;

    return in_irq();
    --
    1.7.5.4



    \
     
     \ /
      Last update: 2011-07-16 13:25    [W:0.026 / U:59.616 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site