Thread (122 messages) 122 messages, 5 authors, 2026-09-02

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

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help