powerpc/64s: Fix doorbell wakeup msgclr optimisation
authorNicholas Piggin <npiggin@gmail.com>
Thu, 2 Apr 2020 12:12:12 +0000 (22:12 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 2 Apr 2020 13:09:53 +0000 (00:09 +1100)
Commit 3282a3da25bd ("powerpc/64: Implement soft interrupt replay in C")
broke the doorbell wakeup optimisation introduced by commit a9af97aa0a12
("powerpc/64s: msgclr when handling doorbell exceptions from system
reset").

This patch restores the msgclr, in C code. It's now done in the system
reset wakeup path rather than doorbell interrupt replay where it used
to be, because it is always the right thing to do in the wakeup case,
but it may be rarely of use in other interrupt replay situations in
which case it's wasted work - we would have to run measurements to see
if that was a worthwhile optimisation, and I suspect it would not be.

The results are similar to those in the original commit, test on POWER8
of context_switch selftests benchmark with polling idle disabled (e.g.,
always nap, giving cross-CPU IPIs) gives the following results:

                                  broken           patched
  Different threads, same core:   317k/s           375k/s    +18.7%
  Different cores:                280k/s           282k/s     +1.0%

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/20200402121212.1118218-1-npiggin@gmail.com
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/irq.c

index 18bbce143084b1857cd63c3e7beefb4240c9521b..728ccb0f560ce7302258e9b6fa788d27c7ca8e31 100644 (file)
@@ -3121,22 +3121,3 @@ handle_dabr_fault:
        li      r5,SIGSEGV
        bl      bad_page_fault
        b       interrupt_return
-
-/*
- * When doorbell is triggered from system reset wakeup, the message is
- * not cleared, so it would fire again when EE is enabled.
- *
- * When coming from local_irq_enable, there may be the same problem if
- * we were hard disabled.
- *
- * Execute msgclr to clear pending exceptions before handling it.
- */
-h_doorbell_common_msgclr:
-       LOAD_REG_IMMEDIATE(r3, PPC_DBELL_MSGTYPE << (63-36))
-       PPC_MSGCLR(3)
-       b       h_doorbell_common_virt
-
-doorbell_super_common_msgclr:
-       LOAD_REG_IMMEDIATE(r3, PPC_DBELL_MSGTYPE << (63-36))
-       PPC_MSGCLRP(3)
-       b       doorbell_super_common_virt
index a25ed47087ee24f93b610a40263008ed19aac640..1f1169856dc848ab7325f6b8cfe91d498c84b27f 100644 (file)
@@ -527,6 +527,19 @@ void irq_set_pending_from_srr1(unsigned long srr1)
                return;
        }
 
+       if (reason == PACA_IRQ_DBELL) {
+               /*
+                * When doorbell triggers a system reset wakeup, the message
+                * is not cleared, so if the doorbell interrupt is replayed
+                * and the IPI handled, the doorbell interrupt would still
+                * fire when EE is enabled.
+                *
+                * To avoid taking the superfluous doorbell interrupt,
+                * execute a msgclr here before the interrupt is replayed.
+                */
+               ppc_msgclr(PPC_DBELL_MSGTYPE);
+       }
+
        /*
         * The 0 index (SRR1[42:45]=b0000) must always evaluate to 0,
         * so this can be called unconditionally with the SRR1 wake