Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9af97aa authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

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: default avatarGautham R. Shenoy <ego@linux.vnet.ibm.com>
Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 771d4304
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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 | \
+1 −0
Original line number Diff line number Diff line
@@ -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));
+21 −2
Original line number Diff line number Diff line
@@ -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