diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2020-09-15 14:46:45 +0300 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2020-10-06 15:22:23 +0300 |
commit | 903fd31d3212ab72d564c68f6cfb5d04db68773e (patch) | |
tree | 0b5c217be7466699a323f107ffa04590f728e7ec /arch/powerpc/kernel | |
parent | cdb1ea0276bd6a225aa1203b4829b8c3c0d4d069 (diff) | |
download | linux-903fd31d3212ab72d564c68f6cfb5d04db68773e.tar.xz |
powerpc/64: fix irq replay missing preempt
Prior to commit 3282a3da25bd ("powerpc/64: Implement soft interrupt
replay in C"), replayed interrupts returned by the regular interrupt
exit code, which performs preemption in case an interrupt had set
need_resched.
This logic was missed by the conversion. Adding preempt_disable/enable
around the interrupt replay and final irq enable will reschedule if
needed.
Fixes: 3282a3da25bd ("powerpc/64: Implement soft interrupt replay in C")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200915114650.3980244-1-npiggin@gmail.com
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/irq.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index bf21ebd36190..77019699606a 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -368,6 +368,12 @@ notrace void arch_local_irq_restore(unsigned long mask) } } + /* + * Disable preempt here, so that the below preempt_enable will + * perform resched if required (a replayed interrupt may set + * need_resched). + */ + preempt_disable(); irq_soft_mask_set(IRQS_ALL_DISABLED); trace_hardirqs_off(); @@ -377,6 +383,7 @@ notrace void arch_local_irq_restore(unsigned long mask) trace_hardirqs_on(); irq_soft_mask_set(IRQS_ENABLED); __hard_irq_enable(); + preempt_enable(); } EXPORT_SYMBOL(arch_local_irq_restore); |