lkml.org 
[lkml]   [2020]   [Oct]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 02/11 v2] ftrace: Add ftrace_test_recursion_trylock() helper function
    From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

    To make it easier for ftrace callbacks to have recursion protection, provide
    a ftrace_test_recursion_trylock() and ftrace_test_recursion_unlock() helper
    that tests for recursion.

    Link: https://lkml.kernel.org/r/20201028115612.634927593@goodmis.org

    Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
    ---
    include/linux/trace_recursion.h | 25 +++++++++++++++++++++++++
    kernel/trace/trace_functions.c | 12 +++++-------
    2 files changed, 30 insertions(+), 7 deletions(-)

    diff --git a/include/linux/trace_recursion.h b/include/linux/trace_recursion.h
    index dbb7b6d4c94c..f2a949dbfec7 100644
    --- a/include/linux/trace_recursion.h
    +++ b/include/linux/trace_recursion.h
    @@ -183,5 +183,30 @@ static __always_inline void trace_clear_recursion(int bit)
    current->trace_recursion = val;
    }

    +/**
    + * ftrace_test_recursion_trylock - tests for recursion in same context
    + *
    + * Use this for ftrace callbacks. This will detect if the function
    + * tracing recursed in the same context (normal vs interrupt),
    + *
    + * Returns: -1 if a recursion happened.
    + * >= 0 if no recursion
    + */
    +static __always_inline int ftrace_test_recursion_trylock(void)
    +{
    + return trace_test_and_set_recursion(TRACE_FTRACE_START, TRACE_FTRACE_MAX);
    +}
    +
    +/**
    + * ftrace_test_recursion_unlock - called when function callback is complete
    + * @bit: The return of a successful ftrace_test_recursion_trylock()
    + *
    + * This is used at the end of a ftrace callback.
    + */
    +static __always_inline void ftrace_test_recursion_unlock(int bit)
    +{
    + trace_clear_recursion(bit);
    +}
    +
    #endif /* CONFIG_TRACING */
    #endif /* _LINUX_TRACE_RECURSION_H */
    diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
    index 2c2126e1871d..943756c01190 100644
    --- a/kernel/trace/trace_functions.c
    +++ b/kernel/trace/trace_functions.c
    @@ -141,22 +141,20 @@ function_trace_call(unsigned long ip, unsigned long parent_ip,
    if (unlikely(!tr->function_enabled))
    return;

    + bit = ftrace_test_recursion_trylock();
    + if (bit < 0)
    + return;
    +
    pc = preempt_count();
    preempt_disable_notrace();

    - bit = trace_test_and_set_recursion(TRACE_FTRACE_START, TRACE_FTRACE_MAX);
    - if (bit < 0)
    - goto out;
    -
    cpu = smp_processor_id();
    data = per_cpu_ptr(tr->array_buffer.data, cpu);
    if (!atomic_read(&data->disabled)) {
    local_save_flags(flags);
    trace_function(tr, ip, parent_ip, flags, pc);
    }
    - trace_clear_recursion(bit);
    -
    - out:
    + ftrace_test_recursion_unlock(bit);
    preempt_enable_notrace();
    }

    --
    2.28.0

    \
     
     \ /
      Last update: 2020-10-30 22:41    [W:3.130 / U:0.372 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site