Commit d099dbfd authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

cpuidle: tracing: Warn about !rcu_is_watching()



When using noinstr, WARN when tracing hits when RCU is disabled.

Suggested-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20230126151323.466670589@infradead.org
parent 5a5d7e9b
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -135,6 +135,21 @@ extern void ftrace_record_recursion(unsigned long ip, unsigned long parent_ip);
# define do_ftrace_record_recursion(ip, pip)	do { } while (0)
#endif

#ifdef CONFIG_ARCH_WANTS_NO_INSTR
# define trace_warn_on_no_rcu(ip)					\
	({								\
		bool __ret = !rcu_is_watching();			\
		if (__ret && !trace_recursion_test(TRACE_RECORD_RECURSION_BIT)) { \
			trace_recursion_set(TRACE_RECORD_RECURSION_BIT); \
			WARN_ONCE(true, "RCU not on for: %pS\n", (void *)ip); \
			trace_recursion_clear(TRACE_RECORD_RECURSION_BIT); \
		}							\
		__ret;							\
	})
#else
# define trace_warn_on_no_rcu(ip)	false
#endif

/*
 * Preemption is promised to be disabled when return bit >= 0.
 */
@@ -144,6 +159,9 @@ static __always_inline int trace_test_and_set_recursion(unsigned long ip, unsign
	unsigned int val = READ_ONCE(current->trace_recursion);
	int bit;

	if (trace_warn_on_no_rcu(ip))
		return -1;

	bit = trace_get_context_bit() + start;
	if (unlikely(val & (1 << bit))) {
		/*