]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: xgene-msi: Make per-CPU interrupt setup robust
authorMarc Zyngier <maz@kernel.org>
Tue, 8 Jul 2025 17:33:56 +0000 (18:33 +0100)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 22 Jul 2025 20:33:16 +0000 (15:33 -0500)
The way the per-CPU interrupts are dealt with in the XGene MSI
driver isn't great:

- the affinity is set after the interrupt is enabled

- nothing prevents userspace from moving the interrupt around

- the affinity setting code pointlessly allocates memory

- the driver checks for conditions that cannot possibly happen

Address all of this in one go, resulting in slightly simpler setup
code.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://lore.kernel.org/r/20250708173404.1278635-6-maz@kernel.org
drivers/pci/controller/pci-xgene-msi.c

index b05ec8b0bb93f1d0d1aa44a750b177befae4e6fc..5b69286689177acc6ba613bbeac52464201829e6 100644 (file)
@@ -355,40 +355,26 @@ static int xgene_msi_hwirq_alloc(unsigned int cpu)
 {
        struct xgene_msi *msi = &xgene_msi_ctrl;
        struct xgene_msi_group *msi_group;
-       cpumask_var_t mask;
        int i;
        int err;
 
        for (i = cpu; i < NR_HW_IRQS; i += msi->num_cpus) {
                msi_group = &msi->msi_groups[i];
-               if (!msi_group->gic_irq)
-                       continue;
-
-               irq_set_chained_handler_and_data(msi_group->gic_irq,
-                       xgene_msi_isr, msi_group);
 
                /*
                 * Statically allocate MSI GIC IRQs to each CPU core.
                 * With 8-core X-Gene v1, 2 MSI GIC IRQs are allocated
                 * to each core.
                 */
-               if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
-                       cpumask_clear(mask);
-                       cpumask_set_cpu(cpu, mask);
-                       err = irq_set_affinity(msi_group->gic_irq, mask);
-                       if (err)
-                               pr_err("failed to set affinity for GIC IRQ");
-                       free_cpumask_var(mask);
-               } else {
-                       pr_err("failed to alloc CPU mask for affinity\n");
-                       err = -EINVAL;
-               }
-
+               irq_set_status_flags(msi_group->gic_irq, IRQ_NO_BALANCING);
+               err = irq_set_affinity(msi_group->gic_irq, cpumask_of(cpu));
                if (err) {
-                       irq_set_chained_handler_and_data(msi_group->gic_irq,
-                                                        NULL, NULL);
+                       pr_err("failed to set affinity for GIC IRQ");
                        return err;
                }
+
+               irq_set_chained_handler_and_data(msi_group->gic_irq,
+                       xgene_msi_isr, msi_group);
        }
 
        return 0;
@@ -402,9 +388,6 @@ static int xgene_msi_hwirq_free(unsigned int cpu)
 
        for (i = cpu; i < NR_HW_IRQS; i += msi->num_cpus) {
                msi_group = &msi->msi_groups[i];
-               if (!msi_group->gic_irq)
-                       continue;
-
                irq_set_chained_handler_and_data(msi_group->gic_irq, NULL,
                                                 NULL);
        }