Re: [PATCH] MIPS: loongson64: add IRQ work based on self-IPI

From: Huacai Chen

Date: Tue Jun 23 2026 - 21:56:27 EST


Reviewed-by: Huacai Chen <chenhuacai@xxxxxxxxxxx>

On Wed, Jun 24, 2026 at 1:28 AM Xi Ruoyao <xry111@xxxxxxxxxxx> wrote:
>
> Since the commit 91840be8f710 ("irq_work: Fix use-after-free in
> irq_work_single() on PREEMPT_RT"), we observed the performance of
> execve() is significantly impacted on MIPS.
>
> While we are unsure how that commit caused the impact or how to improve
> it (or even if it can be improved at all), implementing IRQ work with
> self-IPI seems able to mitigate the impaction.
>
> Perhaps this can/should be implemented for other MIPS architecture
> processors as well, but we don't have the enough knowledge of them, nor
> access to the hardware. So only implement it for loongson64 here.
>
> Link: https://lore.kernel.org/6be1cdd5f91dd7418a32ff372a6f3ae259b19195.camel@xxxxxxxxxxx/
> Signed-off-by: Xi Ruoyao <xry111@xxxxxxxxxxx>
> ---
> arch/mips/include/asm/irq_work.h | 9 +++++++++
> arch/mips/include/asm/smp.h | 2 ++
> arch/mips/loongson64/smp.c | 10 ++++++++++
> 3 files changed, 21 insertions(+)
> create mode 100644 arch/mips/include/asm/irq_work.h
>
> diff --git a/arch/mips/include/asm/irq_work.h b/arch/mips/include/asm/irq_work.h
> new file mode 100644
> index 000000000000..d4fa2d80aabc
> --- /dev/null
> +++ b/arch/mips/include/asm/irq_work.h
> @@ -0,0 +1,9 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef _ASM_MIPS_IRQ_WORK_H
> +#define _ASM_MIPS_IRQ_WORK_H
> +static inline bool arch_irq_work_has_interrupt(void)
> +{
> + return IS_ENABLED(CONFIG_MACH_LOONGSON64) && IS_ENABLED(CONFIG_SMP);
> +}
> +#endif /* _ASM_MIPS_IRQ_WORK_H */
> diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
> index 2427d76f953f..a545568f1cac 100644
> --- a/arch/mips/include/asm/smp.h
> +++ b/arch/mips/include/asm/smp.h
> @@ -50,6 +50,8 @@ extern int __cpu_logical_map[NR_CPUS];
> #define SMP_CALL_FUNCTION 0x2
> /* Octeon - Tell another core to flush its icache */
> #define SMP_ICACHE_FLUSH 0x4
> +/* Loongson64 - Self IPI for IRQ work */
> +#define SMP_IRQ_WORK 0x8
>
> /* Mask of CPUs which are currently definitely operating coherently */
> extern cpumask_t cpu_coherent_mask;
> diff --git a/arch/mips/loongson64/smp.c b/arch/mips/loongson64/smp.c
> index 147acd972a07..e584299d0fde 100644
> --- a/arch/mips/loongson64/smp.c
> +++ b/arch/mips/loongson64/smp.c
> @@ -381,6 +381,13 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
> ipi_write_action(cpu_logical_map(i), (u32)action);
> }
>
> +#ifdef CONFIG_IRQ_WORK
> +void arch_irq_work_raise(void)
> +{
> + loongson3_send_ipi_single(smp_processor_id(), SMP_IRQ_WORK);
> +}
> +#endif
> +
> static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id)
> {
> int cpu = smp_processor_id();
> @@ -397,6 +404,9 @@ static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id)
> irq_exit();
> }
>
> + if (action & SMP_IRQ_WORK)
> + irq_work_run();
> +
> return IRQ_HANDLED;
> }
>
> --
> 2.54.0
>