[RFC PATCH v2 39/45] arm64: smp: Fall back to IRQ when IPI NMI request fails
Vladimir Murzin
vladimir.murzin at arm.com
Fri Aug 21 03:16:34 PDT 2026
On 8/13/26 10:23, Jinjie Ruan wrote:
>
> 在 2026/7/28 0:34, Vladimir Murzin 写道:
>> 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 <vladimir.murzin at arm.com>
>
> 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
More information about the linux-arm-kernel
mailing list