[PATCH v3 1/6] powerpc/64/interrupt: make normal synchronous interrupts enable MSR[EE] if possible

Christophe Leroy christophe.leroy at csgroup.eu
Thu Sep 23 15:05:04 AEST 2021



Le 22/09/2021 à 16:54, Nicholas Piggin a écrit :
> Make synchronous interrupt handler entry wrappers enable MSR[EE] if
> MSR[EE] was enabled in the interrupted context. IRQs are soft-disabled
> at this point so there is no change to high level code, but it's a
> masked interrupt could fire.
> 
> This is a performance disadvantage for interrupts which do not later
> call interrupt_cond_local_irq_enable(), because an an additional mtmsrd
> or wrtee instruction is executed. However the important synchronous
> interrupts (e.g., page fault) do enable interrupts, so the performance
> disadvantage is mostly avoided.
> 
> In the next patch, MSR[RI] enabling can be combined with MSR[EE]
> enabling, which mitigates the performance drop for the former and gives
> a performance advanage for the latter interrupts, on 64s machines. 64e
> is coming along for the ride for now to avoid divergences with 64s in
> this tricky code.
> 
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
> ---
>   arch/powerpc/include/asm/interrupt.h | 19 ++++++++++++++++++-
>   1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
> index b76ab848aa0d..3802390d8eea 100644
> --- a/arch/powerpc/include/asm/interrupt.h
> +++ b/arch/powerpc/include/asm/interrupt.h
> @@ -150,7 +150,20 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup
>   #ifdef CONFIG_PPC64
>   	if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED)
>   		trace_hardirqs_off();
> -	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
> +
> +	/*
> +	 * If the interrupt was taken with HARD_DIS clear, then enable MSR[EE].
> +	 * Asynchronous interrupts get here with HARD_DIS set (see below), so
> +	 * this enables MSR[EE] for synchronous interrupts. IRQs remain
> +	 * soft-masked. The interrupt handler may later call
> +	 * interrupt_cond_local_irq_enable() to achieve a regular process
> +	 * context.
> +	 */
> +	if (!(local_paca->irq_happened & PACA_IRQ_HARD_DIS)) {
> +		if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
> +			BUG_ON(!(regs->msr & MSR_EE));

Could be:
	BUG_ON(IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG) && !(regs->msr & 
MSR_EE));

> +		__hard_irq_enable();
> +	}
>   
>   	if (user_mode(regs)) {
>   		CT_WARN_ON(ct_state() != CONTEXT_USER);
> @@ -200,6 +213,10 @@ static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interrupt
>   
>   static inline void interrupt_async_enter_prepare(struct pt_regs *regs, struct interrupt_state *state)
>   {
> +#ifdef CONFIG_PPC64
> +	/* Ensure interrupt_enter_prepare does not enable MSR[EE] */
> +	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
> +#endif
>   #ifdef CONFIG_PPC_BOOK3S_64
>   	if (cpu_has_feature(CPU_FTR_CTRL) &&
>   	    !test_thread_local_flags(_TLF_RUNLATCH))
> 


More information about the Linuxppc-dev mailing list