]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Fix mismerge of the arm64 / timer-core interrupt handling changes master
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 Apr 2026 06:03:02 +0000 (23:03 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 Apr 2026 06:03:02 +0000 (23:03 -0700)
Commit c43267e6794a ("Merge tag 'arm64-upstream' of git://...") had a
conflict in the irq entry/exit code due to commit c5538d0141b3 ("entry:
Split kernel mode logic from irqentry_{enter,exit}()") having moved the
core code in irqentry_enter/exit() from kernel/entry/common.c into
helper inline functions in include/linux/irq-entry-common.h.

On the other side of the merge, the timer-core code had introduced
deferred hrtimer rearming infrastructure in commit 0e98eb14814e ("entry:
Prepare for deferred hrtimer rearming"), adding two calls to
hrtimer_rearm_deferred() in irqentry_enter().

When merging the two, moving the two calls to the new location wasn't a
problem, but afterwards I had made the mistake of looking what had
happened in linux-next.  And linux-next had a very different merge
resolution in commit 04f02dc3ea74 ("Merge tag 'entry-for-arm64-26-04-08'
into sched/hrtick"), which had unified the two calls into one single
call-site in irqentry_exit_to_kernel_mode_preempt().

And that merge resolution looked cleverer than the straightforward one I
had done, so I re-did my merge the way it had been done in linux-next.

But it turns out nobody apparently tests linux-next, and the merge in
linux-next was just wrong.

The difference is that hrtimer_rearm_deferred() doesn't get called at
all for the case when state.exit_rcu is true, and the boot will
typically fail due to timers not triggering correctly.

So this undoes the "clever" merge, and does the straightforward one
instead.

Fixes: c43267e6794a ("Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux"
Reported-and-tested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Link: https://lore.kernel.org/all/CAADnVQJ=MoiX4=guPWhL9vtnAELkpNx=GNm8RA1-aV424UFz2A@mail.gmail.com/
Link: https://lore.kernel.org/all/CAHk-=wg8+BER4VyFKG3rnPi2gXxbf-jbHS=EU+xhFqGVQfbutw@mail.gmail.com/
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/irq-entry-common.h

index 7ab41eec549fe6c88368053ca7b2223a4ee2b643..167fba7dbf043fb9b28f8fbb36b84e0759bdebf2 100644 (file)
@@ -474,8 +474,6 @@ static inline void irqentry_exit_to_kernel_mode_preempt(struct pt_regs *regs,
 
        if (IS_ENABLED(CONFIG_PREEMPTION))
                irqentry_exit_cond_resched();
-
-       hrtimer_rearm_deferred();
 }
 
 /**
@@ -501,6 +499,7 @@ irqentry_exit_to_kernel_mode_after_preempt(struct pt_regs *regs, irqentry_state_
                 */
                if (state.exit_rcu) {
                        instrumentation_begin();
+                       hrtimer_rearm_deferred();
                        /* Tell the tracer that IRET will enable interrupts */
                        trace_hardirqs_on_prepare();
                        lockdep_hardirqs_on_prepare();
@@ -511,6 +510,7 @@ irqentry_exit_to_kernel_mode_after_preempt(struct pt_regs *regs, irqentry_state_
                }
 
                instrumentation_begin();
+               hrtimer_rearm_deferred();
                /* Covers both tracing and lockdep */
                trace_hardirqs_on();
                instrumentation_end();