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
This commit is contained in:
parent
99cf983cc8
commit
8e12ab7c0e
1 changed files with 11 additions and 9 deletions
|
@ -222,7 +222,16 @@ static void noinstr arm64_exit_el1_dbg(struct pt_regs *regs)
|
||||||
|
|
||||||
static void __sched arm64_preempt_schedule_irq(void)
|
static void __sched arm64_preempt_schedule_irq(void)
|
||||||
{
|
{
|
||||||
lockdep_assert_irqs_disabled();
|
if (!IS_ENABLED(CONFIG_PREEMPTION))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: thread_info::preempt_count includes both thread_info::count
|
||||||
|
* and thread_info::need_resched, and is not equivalent to
|
||||||
|
* preempt_count().
|
||||||
|
*/
|
||||||
|
if (READ_ONCE(current_thread_info()->preempt_count) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DAIF.DA are cleared at the start of IRQ/FIQ handling, and when GIC
|
* 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,
|
||||||
do_interrupt_handler(regs, handler);
|
do_interrupt_handler(regs, handler);
|
||||||
irq_exit_rcu();
|
irq_exit_rcu();
|
||||||
|
|
||||||
/*
|
arm64_preempt_schedule_irq();
|
||||||
* Note: thread_info::preempt_count includes both thread_info::count
|
|
||||||
* and thread_info::need_resched, and is not equivalent to
|
|
||||||
* preempt_count().
|
|
||||||
*/
|
|
||||||
if (IS_ENABLED(CONFIG_PREEMPTION) &&
|
|
||||||
READ_ONCE(current_thread_info()->preempt_count) == 0)
|
|
||||||
arm64_preempt_schedule_irq();
|
|
||||||
|
|
||||||
exit_to_kernel_mode(regs);
|
exit_to_kernel_mode(regs);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue