Skip to content

Commit 8e12ab7

Browse files
mrutland-armPeter Zijlstra
authored andcommitted
arm64: entry: Centralize preemption decision
For historical reasons, the decision of whether or not to preempt is spread across arm64_preempt_schedule_irq() and __el1_irq(), and it would be clearer if this were all in one place. Also, arm64_preempt_schedule_irq() calls lockdep_assert_irqs_disabled(), but this is redundant, as we have a subsequent identical assertion in __exit_to_kernel_mode(), and preempt_schedule_irq() will BUG_ON(!irqs_disabled()) anyway. This patch removes the redundant assertion and centralizes the preemption decision making within arm64_preempt_schedule_irq(). Other than the slight change to assertion behaviour, there should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Ard Biesheuvel <ardb@kernel.org> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Frederic Weisbecker <frederic@kernel.org> Link: https://lore.kernel.org/r/20220214165216.2231574-7-mark.rutland@arm.com
1 parent 99cf983 commit 8e12ab7

1 file changed

Lines changed: 11 additions & 9 deletions

File tree

arch/arm64/kernel/entry-common.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,16 @@ static void noinstr arm64_exit_el1_dbg(struct pt_regs *regs)
222222

223223
static void __sched arm64_preempt_schedule_irq(void)
224224
{
225-
lockdep_assert_irqs_disabled();
225+
if (!IS_ENABLED(CONFIG_PREEMPTION))
226+
return;
227+
228+
/*
229+
* Note: thread_info::preempt_count includes both thread_info::count
230+
* and thread_info::need_resched, and is not equivalent to
231+
* preempt_count().
232+
*/
233+
if (READ_ONCE(current_thread_info()->preempt_count) != 0)
234+
return;
226235

227236
/*
228237
* DAIF.DA are cleared at the start of IRQ/FIQ handling, and when GIC
@@ -438,14 +447,7 @@ static __always_inline void __el1_irq(struct pt_regs *regs,
438447
do_interrupt_handler(regs, handler);
439448
irq_exit_rcu();
440449

441-
/*
442-
* Note: thread_info::preempt_count includes both thread_info::count
443-
* and thread_info::need_resched, and is not equivalent to
444-
* preempt_count().
445-
*/
446-
if (IS_ENABLED(CONFIG_PREEMPTION) &&
447-
READ_ONCE(current_thread_info()->preempt_count) == 0)
448-
arm64_preempt_schedule_irq();
450+
arm64_preempt_schedule_irq();
449451

450452
exit_to_kernel_mode(regs);
451453
}

0 commit comments

Comments
 (0)