cpuidle: lib/bug: Disable rcu_is_watching() during WARN/BUG

In order to avoid WARN/BUG from generating nested or even recursive
warnings, force rcu_is_watching() true during
WARN/lockdep_rcu_suspicious().

Notably things like unwinding the stack can trigger rcu_dereference()
warnings, which then triggers more unwinding which then triggers more
warnings etc..

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20230126151323.408156109@infradead.org
This commit is contained in:
Peter Zijlstra
2023-01-26 16:08:31 +01:00
committed by Ingo Molnar
parent 393e2ea30a
commit 5a5d7e9bad
4 changed files with 49 additions and 1 deletions

View File

@@ -130,9 +130,36 @@ static __always_inline unsigned long ct_state_inc(int incby)
return arch_atomic_add_return(incby, this_cpu_ptr(&context_tracking.state));
}
static __always_inline bool warn_rcu_enter(void)
{
bool ret = false;
/*
* Horrible hack to shut up recursive RCU isn't watching fail since
* lots of the actual reporting also relies on RCU.
*/
preempt_disable_notrace();
if (rcu_dynticks_curr_cpu_in_eqs()) {
ret = true;
ct_state_inc(RCU_DYNTICKS_IDX);
}
return ret;
}
static __always_inline void warn_rcu_exit(bool rcu)
{
if (rcu)
ct_state_inc(RCU_DYNTICKS_IDX);
preempt_enable_notrace();
}
#else
static inline void ct_idle_enter(void) { }
static inline void ct_idle_exit(void) { }
static __always_inline bool warn_rcu_enter(void) { return false; }
static __always_inline void warn_rcu_exit(bool rcu) { }
#endif /* !CONFIG_CONTEXT_TRACKING_IDLE */
#endif