tick: Move broadcast cancellation up to CPUHP_AP_TICK_DYING
authorFrederic Weisbecker <frederic@kernel.org>
Sun, 25 Feb 2024 22:55:01 +0000 (23:55 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 26 Feb 2024 10:37:32 +0000 (11:37 +0100)
The broadcast shutdown code is executed through a random explicit call
within stop machine from the outgoing CPU.

However the tick broadcast is a midware between the tick callback and
the clocksource, therefore it makes more sense to shut it down after the
tick callback and before the clocksource drivers.

Move it instead to the common tick shutdown CPU hotplug state where
related operations can be ordered from highest to lowest level.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240225225508.11587-10-frederic@kernel.org
include/linux/tick.h
kernel/cpu.c
kernel/time/tick-common.c
kernel/time/tick-internal.h

index afff4c207bd8dad8e03546a8a013fa8af46619c4..c7840ae8ebafbfb9c3964eb6c200f3c4cf878e1a 100644 (file)
@@ -73,12 +73,6 @@ extern void tick_broadcast_control(enum tick_broadcast_mode mode);
 static inline void tick_broadcast_control(enum tick_broadcast_mode mode) { }
 #endif /* BROADCAST */
 
-#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_HOTPLUG_CPU)
-extern void tick_offline_cpu(unsigned int cpu);
-#else
-static inline void tick_offline_cpu(unsigned int cpu) { }
-#endif
-
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 extern int tick_broadcast_oneshot_control(enum tick_broadcast_state state);
 #else
index 263508073da896d17f1ce90906511c4e9f3c077a..5a8ad4f5ccf33695454bc4ebcb0385be83d6e3ff 100644 (file)
@@ -1324,8 +1324,6 @@ static int take_cpu_down(void *_param)
         */
        cpuhp_invoke_callback_range_nofail(false, cpu, st, target);
 
-       /* Remove CPU from timer broadcasting */
-       tick_offline_cpu(cpu);
        /* Park the stopper thread */
        stop_machine_park(cpu);
        return 0;
index b4af8c743b737fe2628eaf61855c154c467a0c95..522414089c0d793d66d1f31508aa8706c7c68aaf 100644 (file)
@@ -412,6 +412,9 @@ int tick_cpu_dying(unsigned int dying_cpu)
 
        tick_cancel_sched_timer(dying_cpu);
 
+       /* Remove CPU from timer broadcasting */
+       tick_offline_cpu(dying_cpu);
+
        return 0;
 }
 
index a3243c4ac45fa5e83f19e5ad6707c6c01b4d9ee3..5f2105e637bdf0df16718f35afbc9cc0ca4edec5 100644 (file)
@@ -142,8 +142,10 @@ static inline bool tick_broadcast_oneshot_available(void) { return tick_oneshot_
 #endif /* !(BROADCAST && ONESHOT) */
 
 #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_HOTPLUG_CPU)
+extern void tick_offline_cpu(unsigned int cpu);
 extern void tick_broadcast_offline(unsigned int cpu);
 #else
+static inline void tick_offline_cpu(unsigned int cpu) { }
 static inline void tick_broadcast_offline(unsigned int cpu) { }
 #endif