diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-20 15:30:08 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-20 15:30:08 -0700 |
| commit | ccbc9fdb327d164f2a0f423e93499058e8add68c (patch) | |
| tree | 948baa427c4610f370154283c9635602072d31c9 | |
| parent | 65e9974ae2678c218804d30a1b5f7c60532705d2 (diff) | |
| parent | 4096fd0e8eaea13ebe5206700b33f49635ae18e5 (diff) | |
Merge tag 'timers-urgent-2026-04-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fix from Ingo Molnar:
"Fix timer stalls caused by incorrect handling of the
dev->next_event_forced flag"
* tag 'timers-urgent-2026-04-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
clockevents: Add missing resets of the next_event_forced flag
| -rw-r--r-- | kernel/time/clockevents.c | 7 | ||||
| -rw-r--r-- | kernel/time/tick-broadcast.c | 1 |
2 files changed, 7 insertions, 1 deletions
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index b4d730604972..5e22697b098d 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -94,6 +94,9 @@ static int __clockevents_switch_state(struct clock_event_device *dev, if (dev->features & CLOCK_EVT_FEAT_DUMMY) return 0; + /* On state transitions clear the forced flag unconditionally */ + dev->next_event_forced = 0; + /* Transition with new state-specific callbacks */ switch (state) { case CLOCK_EVT_STATE_DETACHED: @@ -366,8 +369,10 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, b if (delta > (int64_t)dev->min_delta_ns) { delta = min(delta, (int64_t) dev->max_delta_ns); cycles = ((u64)delta * dev->mult) >> dev->shift; - if (!dev->set_next_event((unsigned long) cycles, dev)) + if (!dev->set_next_event((unsigned long) cycles, dev)) { + dev->next_event_forced = 0; return 0; + } } if (dev->next_event_forced) diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 7e57fa31ee26..115e0bf01276 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -108,6 +108,7 @@ static struct clock_event_device *tick_get_oneshot_wakeup_device(int cpu) static void tick_oneshot_wakeup_handler(struct clock_event_device *wd) { + wd->next_event_forced = 0; /* * If we woke up early and the tick was reprogrammed in the * meantime then this may be spurious but harmless. |
