powerpc/64s: msgclr when handling doorbell exceptions from system reset
msgsnd doorbell exceptions are cleared when the doorbell interrupt is taken. However if a doorbell exception causes a system reset interrupt wake from power saving state, the message is not cleared. Processing the doorbell from the system reset interrupt requires msgclr to avoid taking the exception again. Testing this plus the previous wakup direct patch gives: original wakeup direct msgclr Different threads, same core: 315k/s 264k/s 345k/s Different cores: 235k/s 242k/s 242k/s Net speedup is +10% for same core, and +3% for different core. Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com> Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
771d4304d0
commit
a9af97aa0a
|
@ -56,6 +56,19 @@ static inline void ppc_msgsync(void)
|
|||
: : "i" (CPU_FTR_HVMODE|CPU_FTR_ARCH_300));
|
||||
}
|
||||
|
||||
static inline void _ppc_msgclr(u32 msg)
|
||||
{
|
||||
__asm__ __volatile__ (ASM_FTR_IFSET(PPC_MSGCLR(%1), PPC_MSGCLRP(%1), %0)
|
||||
: : "i" (CPU_FTR_HVMODE), "r" (msg));
|
||||
}
|
||||
|
||||
static inline void ppc_msgclr(enum ppc_dbell type)
|
||||
{
|
||||
u32 msg = PPC_DBELL_TYPE(type);
|
||||
|
||||
_ppc_msgclr(msg);
|
||||
}
|
||||
|
||||
#else /* CONFIG_PPC_BOOK3S */
|
||||
|
||||
#define PPC_DBELL_MSGTYPE PPC_DBELL
|
||||
|
|
|
@ -220,6 +220,7 @@
|
|||
#define PPC_INST_MSGCLR 0x7c0001dc
|
||||
#define PPC_INST_MSGSYNC 0x7c0006ec
|
||||
#define PPC_INST_MSGSNDP 0x7c00011c
|
||||
#define PPC_INST_MSGCLRP 0x7c00015c
|
||||
#define PPC_INST_MTTMR 0x7c0003dc
|
||||
#define PPC_INST_NOP 0x60000000
|
||||
#define PPC_INST_PASTE 0x7c20070d
|
||||
|
@ -409,6 +410,8 @@
|
|||
___PPC_RB(b))
|
||||
#define PPC_MSGSNDP(b) stringify_in_c(.long PPC_INST_MSGSNDP | \
|
||||
___PPC_RB(b))
|
||||
#define PPC_MSGCLRP(b) stringify_in_c(.long PPC_INST_MSGCLRP | \
|
||||
___PPC_RB(b))
|
||||
#define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \
|
||||
__PPC_RA(a) | __PPC_RS(s))
|
||||
#define PPC_POPCNTD(a, s) stringify_in_c(.long PPC_INST_POPCNTD | \
|
||||
|
|
|
@ -746,6 +746,7 @@ int main(void)
|
|||
#endif
|
||||
|
||||
DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER);
|
||||
DEFINE(PPC_DBELL_MSGTYPE, PPC_DBELL_MSGTYPE);
|
||||
|
||||
#ifdef CONFIG_PPC_8xx
|
||||
DEFINE(VIRT_IMMR_BASE, (u64)__fix_to_virt(FIX_IMMR_BASE));
|
||||
|
|
|
@ -1611,6 +1611,25 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
|
|||
bl kernel_bad_stack
|
||||
b 1b
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
doorbell_super_common_msgclr:
|
||||
LOAD_REG_IMMEDIATE(r3, PPC_DBELL_MSGTYPE << (63-36))
|
||||
PPC_MSGCLRP(3)
|
||||
b doorbell_super_common
|
||||
|
||||
/*
|
||||
* Called from arch_local_irq_enable when an interrupt needs
|
||||
* to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate
|
||||
|
@ -1636,13 +1655,13 @@ _GLOBAL(__replay_interrupt)
|
|||
beq hardware_interrupt_common
|
||||
BEGIN_FTR_SECTION
|
||||
cmpwi r3,0xe80
|
||||
beq h_doorbell_common
|
||||
beq h_doorbell_common_msgclr
|
||||
cmpwi r3,0xea0
|
||||
beq h_virt_irq_common
|
||||
cmpwi r3,0xe60
|
||||
beq hmi_exception_common
|
||||
FTR_SECTION_ELSE
|
||||
cmpwi r3,0xa00
|
||||
beq doorbell_super_common
|
||||
beq doorbell_super_common_msgclr
|
||||
ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
|
||||
blr
|
||||
|
|
Loading…
Reference in New Issue