Skip to content

Commit b40341f

Browse files
committed
ftrace: Move RCU is watching check after recursion check
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>
1 parent 851e6f6 commit b40341f

1 file changed

Lines changed: 2 additions & 4 deletions

File tree

kernel/trace/ftrace.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6993,16 +6993,14 @@ static void ftrace_ops_assist_func(unsigned long ip, unsigned long parent_ip,
69936993
{
69946994
int bit;
69956995

6996-
if ((op->flags & FTRACE_OPS_FL_RCU) && !rcu_is_watching())
6997-
return;
6998-
69996996
bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX);
70006997
if (bit < 0)
70016998
return;
70026999

70037000
preempt_disable_notrace();
70047001

7005-
op->func(ip, parent_ip, op, regs);
7002+
if (!(op->flags & FTRACE_OPS_FL_RCU) || rcu_is_watching())
7003+
op->func(ip, parent_ip, op, regs);
70067004

70077005
preempt_enable_notrace();
70087006
trace_clear_recursion(bit);

0 commit comments

Comments
 (0)