Re: [PATCH v2] irq_work: Fix use-after-free in irq_work_single on PREEMPT_RT

From: Xi Ruoyao

Date: Fri Jun 05 2026 - 13:32:56 EST


On Fri, 2026-06-05 at 12:45 +0200, Sebastian Andrzej Siewior wrote:
> On 2026-06-05 18:31:41 [+0800], Xi Ruoyao wrote:
> > Hi,
> >
> > This commit significantly slows down execve() (and perhaps other things)
> > on MIPS.  A very simple program:
>
> This is probably originating from sched_mm_cid_exit(). Can you check?

I've not checked that yet (I have to admit I don't really know how).

On the other hand, Yao Zi told me she speculated this might be related
to the lack of arch_irq_work_raise on MIPS. For mips/loongson64 the IPI
support is already there and we only need 16 lines to implement
arch_irq_work_raise:

diff --git a/arch/mips/include/asm/irq_work.h b/arch/mips/include/asm/irq_work.h
new file mode 100644
index 000000000000..2695e0f94f2f
--- /dev/null
+++ b/arch/mips/include/asm/irq_work.h
@@ -0,0 +1,4 @@
+static inline bool arch_irq_work_has_interrupt(void)
+{
+ return IS_ENABLED(CONFIG_MACH_LOONGSON64) && IS_ENABLED(CONFIG_SMP);
+}
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
index 2427d76f953f..30a036e5bfc4 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
+/* Loongson 3 - 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;
}

With this the performance indeed becomes normal.

--
Xi Ruoyao <xry111@xxxxxxxxxxx>