mirror of
https://github.com/torvalds/linux.git
synced 2026-03-13 23:46:14 +01:00
The timekeeping duty is handed over from the outgoing CPU within stop machine. This works well if CONFIG_NO_HZ_COMMON=n or the tick is in high-res mode. However in low-res dynticks mode, the tick isn't cancelled until the clockevent is shut down, which can happen later. The tick may therefore fire again once IRQs are re-enabled on stop machine and until IRQs are disabled for good upon the last call to idle. That's so many opportunities for a timekeeper to go idle and the outgoing CPU to take over that duty. This is why tick_nohz_idle_stop_tick() is called one last time on idle if the CPU is seen offline: so that the timekeeping duty is handed over again in case the CPU has re-taken the duty. This means there are two timekeeping handovers on CPU down hotplug with different undocumented constraints and purposes: 1) A handover on stop machine for !dynticks || highres. All online CPUs are guaranteed to be non-idle and the timekeeping duty can be safely handed-over. The hrtimer tick is cancelled so it is guaranteed that in dynticks mode the outgoing CPU won't take again the duty. 2) A handover on last idle call for dynticks && lowres. Setting the duty to TICK_DO_TIMER_NONE makes sure that a CPU will take over the timekeeping. Prepare for consolidating the handover to a single place (the first one) with shutting down the low-res tick as well from tick_cancel_sched_timer() as well. This will simplify the handover and unify the tick cancellation between high-res and low-res. 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-15-frederic@kernel.org |
||
|---|---|---|
| .. | ||
| alarmtimer.c | ||
| clockevents.c | ||
| clocksource-wdtest.c | ||
| clocksource.c | ||
| hrtimer.c | ||
| itimer.c | ||
| jiffies.c | ||
| Kconfig | ||
| Makefile | ||
| namespace.c | ||
| ntp.c | ||
| ntp_internal.h | ||
| posix-clock.c | ||
| posix-cpu-timers.c | ||
| posix-stubs.c | ||
| posix-timers.c | ||
| posix-timers.h | ||
| sched_clock.c | ||
| test_udelay.c | ||
| tick-broadcast-hrtimer.c | ||
| tick-broadcast.c | ||
| tick-common.c | ||
| tick-internal.h | ||
| tick-legacy.c | ||
| tick-oneshot.c | ||
| tick-sched.c | ||
| tick-sched.h | ||
| time.c | ||
| time_test.c | ||
| timeconst.bc | ||
| timeconv.c | ||
| timecounter.c | ||
| timekeeping.c | ||
| timekeeping.h | ||
| timekeeping_debug.c | ||
| timekeeping_internal.h | ||
| timer.c | ||
| timer_list.c | ||
| timer_migration.c | ||
| timer_migration.h | ||
| vsyscall.c | ||