diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2024-02-29 15:23:36 +0100 |
---|---|---|
committer | Borislav Petkov (AMD) <bp@alien8.de> | 2024-03-01 21:04:27 +0100 |
commit | 2be2a197ff6c3a659ab9285e1d88cbdc609ac6de (patch) | |
tree | e742ba7b20801029543c26db8d259147194b0c9a /include/linux/tick.h | |
parent | 44c76825d6eefee9eb7ce06c38e1a6632ac7eb7d (diff) | |
download | lwn-2be2a197ff6c3a659ab9285e1d88cbdc609ac6de.tar.gz lwn-2be2a197ff6c3a659ab9285e1d88cbdc609ac6de.zip |
sched/idle: Conditionally handle tick broadcast in default_idle_call()
The x86 architecture has an idle routine for AMD CPUs which are affected
by erratum 400. On the affected CPUs the local APIC timer stops in the
C1E halt state.
It therefore requires tick broadcasting. The invocation of
tick_broadcast_enter()/exit() from this function violates the RCU
constraints because it can end up in lockdep or tracing, which
rightfully triggers a warning.
tick_broadcast_enter()/exit() must be invoked before ct_cpuidle_enter()
and after ct_cpuidle_exit() in default_idle_call().
Add a static branch conditional invocation of tick_broadcast_enter()/exit()
into this function to allow X86 to replace the AMD specific idle code. It's
guarded by a config switch which will be selected by x86. Otherwise it's
a NOOP.
Reported-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20240229142248.266708822@linutronix.de
Diffstat (limited to 'include/linux/tick.h')
-rw-r--r-- | include/linux/tick.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/include/linux/tick.h b/include/linux/tick.h index 716d17f31c45..e134f286df8a 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -12,6 +12,7 @@ #include <linux/cpumask.h> #include <linux/sched.h> #include <linux/rcupdate.h> +#include <linux/static_key.h> #ifdef CONFIG_GENERIC_CLOCKEVENTS extern void __init tick_init(void); @@ -63,6 +64,8 @@ enum tick_broadcast_state { TICK_BROADCAST_ENTER, }; +extern struct static_key_false arch_needs_tick_broadcast; + #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST extern void tick_broadcast_control(enum tick_broadcast_mode mode); #else |