Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cpuidle: tracing: Warn about !rcu_is_watching()

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

Suggested-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20230126151323.466670589@infradead.org

authored by

Peter Zijlstra and committed by
Ingo Molnar
d099dbfd 5a5d7e9b

+18
+18
include/linux/trace_recursion.h
··· 135 135 # define do_ftrace_record_recursion(ip, pip) do { } while (0) 136 136 #endif 137 137 138 + #ifdef CONFIG_ARCH_WANTS_NO_INSTR 139 + # define trace_warn_on_no_rcu(ip) \ 140 + ({ \ 141 + bool __ret = !rcu_is_watching(); \ 142 + if (__ret && !trace_recursion_test(TRACE_RECORD_RECURSION_BIT)) { \ 143 + trace_recursion_set(TRACE_RECORD_RECURSION_BIT); \ 144 + WARN_ONCE(true, "RCU not on for: %pS\n", (void *)ip); \ 145 + trace_recursion_clear(TRACE_RECORD_RECURSION_BIT); \ 146 + } \ 147 + __ret; \ 148 + }) 149 + #else 150 + # define trace_warn_on_no_rcu(ip) false 151 + #endif 152 + 138 153 /* 139 154 * Preemption is promised to be disabled when return bit >= 0. 140 155 */ ··· 158 143 { 159 144 unsigned int val = READ_ONCE(current->trace_recursion); 160 145 int bit; 146 + 147 + if (trace_warn_on_no_rcu(ip)) 148 + return -1; 161 149 162 150 bit = trace_get_context_bit() + start; 163 151 if (unlikely(val & (1 << bit))) {