[RFC PATCH v2 43/45] arm64: smp: Add NMI support for LPI-backed IPIs
Jinjie Ruan
ruanjinjie at huawei.com
Tue Jul 28 05:34:06 PDT 2026
在 2026/7/28 0:34, Vladimir Murzin 写道:
> LPI-backed IPIs are currently always requested and managed as regular
> IRQs. Allow IPIs selected by ipi_should_be_nmi() to be requested as
> NMIs, falling back to regular IRQs when the NMI request fails.
>
It seems FEAT_NMI do not support LPI interrupt.
> Track which IPIs were successfully requested as NMIs so that the
> per-CPU enable and disable paths use the appropriate NMI helpers.
>
> Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
> ---
> arch/arm64/kernel/smp.c | 34 +++++++++++++++++++++++++++++-----
> 1 file changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 9bacdbb2aa44..012633ea8347 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -1123,16 +1123,24 @@ static const struct ipi_irq_ops ipi_sgi_ops = {
>
> static void ipi_lpi_enable(int cpu, int ipi)
> {
> - enable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> + if (test_bit(ipi, get_ipi_nmi_bitmap(cpu)))
> + enable_nmi(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> + else
> + enable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> }
>
> static void ipi_lpi_disable(int cpu, int ipi)
> {
> - disable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> + if (test_bit(ipi, get_ipi_nmi_bitmap(cpu)))
> + disable_nmi_nosync(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> + else
> + disable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> }
>
> static void ipi_lpi_setup(int ipi, int ncpus)
> {
> + bool is_nmi = ipi_should_be_nmi(ipi);
> +
> for (int cpu = 0; cpu < ncpus; cpu++) {
> int err, irq;
>
> @@ -1141,13 +1149,29 @@ static void ipi_lpi_setup(int ipi, int ncpus)
> err = irq_force_affinity(irq, cpumask_of(cpu));
> WARN(err, "Could not force affinity IRQ %d, err=%d\n", irq, err);
>
> - err = request_irq(irq, ipi_handler, IRQF_NO_AUTOEN, "IPI",
> - NULL);
> - WARN(err, "Could not request IRQ %d, err=%d\n", irq, err);
> + /*
> + * Try to request NMI if it should be
> + */
> + if (is_nmi && request_nmi(irq, ipi_handler, IRQF_PERCPU | IRQF_NO_AUTOEN, "IPI", NULL)) {
> + /*
> + * Fallback to regular IRQ
> + */
> + is_nmi = false;
> + }
> + /*
> + * Otherwise regular IRQ
> + */
> + if (!is_nmi) {
> + err = request_irq(irq, ipi_handler, IRQF_NO_AUTOEN, "IPI", NULL);
> + WARN(err, "Could not request IRQ %d, err=%d\n", irq, err);
> + }
>
> irq_set_status_flags(irq, (IRQ_HIDDEN | IRQ_NO_BALANCING_MASK));
>
> get_ipi_desc(cpu, ipi) = irq_to_desc(irq);
> +
> + if (is_nmi)
> + set_bit(ipi, get_ipi_nmi_bitmap(cpu));
> }
> }
>
More information about the linux-arm-kernel
mailing list