[PATCH] clocksource: Prevent immediate watchdog rerun after a delay

From: Karl Mehltretter

Date: Sun Oct 25 2026 - 21:02:43 EST


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@xxxxxxxxx/
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@xxxxxxxxx>
---
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)