The watchdog rewrite made the clocksource check handle long intervals between two measurements, but missed that the timer expiry needs to be rebased after such a delay. When a watchdog invocation is delayed by more than one interval, adding WATCHDOG_INTERVAL to the previous expiry leaves the timer expiry in the past. That causes an immediate second invocation. The resulting short measurement interval can mark a clocksource unstable. Cure this by rearming the timer based on jiffies, which places the next expiry one full watchdog interval into the future. Fixes: 763aacf86f1b ("clocksource: Rewrite watchdog code completely") Closes: https://lore.kernel.org/r/20261010065509.72916-1-kmehltretter@gmail.com/ Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Karl Mehltretter --- The baseline and patched builds used identical configs and initramfs images. Tested on v7.3-rc5 (72d3fcf802c4) with four QEMU 8.2.2 TCG vCPUs. PTRACE_ATTACH stopped only the vCPU 0 TCG thread for 800 ms, six times 12 seconds apart per boot. baseline patched TSC marked unstable 2/3 boots 0/3 boots boots with gaps below 250 ms 3/3 0/3 minimum watchdog gap 0.231 ms 505.484 ms All 18 injected stalls completed for each kernel. kernel/time/clocksource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index f1253f5795c6e..58c0ca11cdc5a 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -673,7 +673,7 @@ static void clocksource_watchdog(struct timer_list *unused) /* Could have been rearmed by a stop/start cycle */ if (!timer_pending(&watchdog_timer)) { - watchdog_timer.expires += WATCHDOG_INTERVAL; + watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; add_timer_local(&watchdog_timer); } } base-commit: 5b0764a53235d3c77e1ed674e836e1b3fe1a4b1f -- 2.39.5 (Apple Git-154)