Skip to content

Commit

Permalink
ftrace: Move RCU is watching check after recursion check
Browse files Browse the repository at this point in the history
The first thing that the ftrace function callback helper functions should do
is to check for recursion. Peter Zijlstra found that when
"rcu_is_watching()" had its notrace removed, it caused perf function tracing
to crash. This is because the call of rcu_is_watching() is tested before
function recursion is checked and and if it is traced, it will cause an
infinite recursion loop.

rcu_is_watching() should still stay notrace, but to prevent this should
never had crashed in the first place. The recursion prevention must be the
first thing done in callback functions.

Link: https://lore.kernel.org/r/20200929112541.GM2628@hirez.programming.kicks-ass.net

Cc: stable@vger.kernel.org
Cc: Paul McKenney <paulmck@kernel.org>
Fixes: c68c0fa ("ftrace: Have ftrace_ops_get_func() handle RCU and PER_CPU flags too")
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reported-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
  • Loading branch information
rostedt committed Sep 29, 2020
1 parent 851e6f6 commit b40341f
Showing 1 changed file with 2 additions and 4 deletions.
6 changes: 2 additions & 4 deletions kernel/trace/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -6993,16 +6993,14 @@ static void ftrace_ops_assist_func(unsigned long ip, unsigned long parent_ip,
{
int bit;

if ((op->flags & FTRACE_OPS_FL_RCU) && !rcu_is_watching())
return;

bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX);
if (bit < 0)
return;

preempt_disable_notrace();

op->func(ip, parent_ip, op, regs);
if (!(op->flags & FTRACE_OPS_FL_RCU) || rcu_is_watching())
op->func(ip, parent_ip, op, regs);

preempt_enable_notrace();
trace_clear_recursion(bit);
Expand Down

0 comments on commit b40341f

Please sign in to comment.