Re: The "clockevents: Prevent timer interrupt starvation" patch causes lockups
From: Eric Naim
Date: Tue Apr 14 2026 - 11:47:15 EST
On 4/14/26 5:20 AM, Hanabishi wrote:
>
> Hello.
>
> Sorry, but this patch as of 7.0 introduced *severe* periodic lockups on my
> Ryzen 7700X machine.
> I see such messages in the log:
>
> clocksource: Long readout interval, skipping watchdog check: cs_nsec:
> 2897344852 wd_nsec: 2897356996
>
> Reverting d6e152d905bdb1f32f9d99775e2f453350399a6a for mainline fixes the
> issue for me.
>
Hi maintainers,
several users from CachyOS has reported this regression as well. We landed on
the same bisection. One of the users that could reproduce this reliably
reproduced this just by watching a YouTube video in a browser, and observed
freezes and stutters when interacting with the system.
I had an LLM generate a fix (patch attached), and it fixed the regression for
that user. Full disclosure: it is written completely by AI, and I am also not
familiar with this subsystem. I just hope that this patch can be helpful in
fixing the regression.
Please don't hesitate to tell me off if utilizing AI in this way is not
helpful, so I can keep this in mind for future contributions.
--
Regards,
Ericdiff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 38570998a19b..37b10045572e 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -332,8 +332,10 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
if (delta > (int64_t)dev->min_delta_ns) {
delta = min(delta, (int64_t) dev->max_delta_ns);
clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
- if (!dev->set_next_event((unsigned long) clc, dev))
+ if (!dev->set_next_event((unsigned long) clc, dev)) {
+ dev->next_event_forced = 0;
return 0;
+ }
}
if (dev->next_event_forced)
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c
index 7472597f3225..bf411472d4f7 100644
--- a/kernel/time/tick-oneshot.c
+++ b/kernel/time/tick-oneshot.c
@@ -34,6 +34,7 @@ int tick_program_event(ktime_t expires, int force)
*/
clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT_STOPPED);
dev->next_event = KTIME_MAX;
+ dev->next_event_forced = 0;
return 0;
}
@@ -43,6 +44,7 @@ int tick_program_event(ktime_t expires, int force)
* before using it.
*/
clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
+ dev->next_event_forced = 0;
}
return clockevents_program_event(dev, expires, force);