diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2017-06-13 23:05:47 +1000 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-06-19 19:46:27 +1000 |
commit | 771d4304d07f080b6ce751e12f3579cb012a1b22 (patch) | |
tree | ec087d9bd222ab6ca1bc8b45c6e97c87570274fc /arch/powerpc/include/asm/hw_irq.h | |
parent | 2525db04d1cc53e1951143d1829aa75a78cc7f76 (diff) | |
download | linux-stable-771d4304d07f080b6ce751e12f3579cb012a1b22.tar.gz linux-stable-771d4304d07f080b6ce751e12f3579cb012a1b22.tar.bz2 linux-stable-771d4304d07f080b6ce751e12f3579cb012a1b22.zip |
powerpc/64s/idle: Process interrupts from system reset wakeup
When the CPU wakes from low power state, it begins at the system reset
interrupt with the exception that caused the wakeup encoded in SRR1.
Today, powernv idle wakeup ignores the wakeup reason (except a special
case for HMI), and the regular interrupt corresponding to the
exception will fire after the idle wakeup exits.
Change this to replay the interrupt from the idle wakeup before
interrupts are hard-enabled.
Test on POWER8 of context_switch selftests benchmark with polling idle
disabled (e.g., always nap, giving cross-CPU IPIs) gives the following
results:
original wakeup direct
Different threads, same core: 315k/s 264k/s
Different cores: 235k/s 242k/s
There is a slowdown for doorbell IPI (same core) case because system
reset wakeup does not clear the message and the doorbell interrupt
fires again needlessly.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/include/asm/hw_irq.h')
-rw-r--r-- | arch/powerpc/include/asm/hw_irq.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index f06112cf8734..c1dd1929342d 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -130,6 +130,7 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs) extern bool prep_irq_for_idle(void); extern bool prep_irq_for_idle_irqsoff(void); +extern void irq_set_pending_from_srr1(unsigned long srr1); #define fini_irq_for_idle_irqsoff() trace_hardirqs_off(); |