Re: [RFC PATCH v2 39/45] arm64: smp: Fall back to IRQ when IPI NMI request fails
From: Vladimir Murzin <hidden>
Date: 2026-08-21 10:16:55
On 8/13/26 10:23, Jinjie Ruan wrote:
在 2026/7/28 0:34, Vladimir Murzin 写道:quoted
Existing IPI setup logic relies on ipi_should_be_nmi() to decide whether to request an NMI (if supported) or an ordinary IRQ. If NMI is not supported, using an ordinary IRQ is acceptable. FEAT_NMI requires complementary support in the interrupt controller. If FEAT_NMI is present but interrupt controller support is absent, request_percpu_nmi() can fail. One way to prevent this would be to extend ipi_should_be_nmi() to also check for interrupt controller support. However, since falling back to an ordinary IRQ is acceptable, treat ipi_should_be_nmi() as a hint instead. Whether an IPI is actually registered as an NMI is determined by the success or failure of request_percpu_nmi(). If the request fails, fall back to request_irq(). Track which IPIs were actually registered as NMIs and use that state in the per-CPU enable and disable paths. This avoids calling the percpu NMI helpers for an IPI that fell back to regular IRQ handling. Signed-off-by: Vladimir Murzin <redacted>Should we replace ipi_should_be_nmi() with test_bit(ipi, get_ipi_nmi_bitmap(cpu) in smp_send_stop()?
Right. We can do something like
@@ -1312,7 +1328,7 @@ void smp_send_stop(void) * If CPUs are still online, try an NMI. There's no excuse for this to * be slow, so we only give them an extra 10 ms to respond. */ - if (num_other_online_cpus() && ipi_should_be_nmi(IPI_CPU_STOP_NMI)) { + if (num_other_online_cpus() && ipi_is_nmi(smp_processor_id(), IPI_CPU_STOP_NMI)) { smp_rmb(); cpumask_copy(&mask, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &mask);
where +#define ipi_is_nmi(__cpu, __ipi) test_bit(__ipi, get_ipi_nmi_bitmap(__cpu)) can be used in other places to simpify the code
irq_desc_get_irq(get_ipi_desc(cpu, ipi)) has been used more than 3 times, can we define a new macro for use? git grep "irq_desc_get_irq(get_ipi_desc(cpu, ipi))" arch/arm64/kernel/smp.c: enable_nmi(irq_desc_get_irq(get_ipi_desc(cpu, ipi))); arch/arm64/kernel/smp.c: enable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi))); arch/arm64/kernel/smp.c: disable_nmi_nosync(irq_desc_get_irq(get_ipi_desc(cpu, ipi))); arch/arm64/kernel/smp.c: disable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
I assume you did grep after full series applied, since irq_desc_get_irq(get_ipi_desc(cpu, ipi)) comes from LPI flow. Anyway, we can easily avoid some duplication and get usage of irq_desc_get_irq(get_ipi_desc(cpu, ipi)) back to two $ git grep "irq_desc_get_irq(get_ipi_desc(cpu, ipi))" arch/arm64/kernel/smp.c: int irq = irq_desc_get_irq(get_ipi_desc(cpu, ipi)); arch/arm64/kernel/smp.c: int irq = irq_desc_get_irq(get_ipi_desc(cpu, ipi)); Cheers Vladimir