Skip to content

Commit 553c3c3

Browse files
rrendecabhishek-6246
authored andcommitted
PCI: dwc: Enable MSI affinity support
Leverage the interrupt redirection infrastructure to enable CPU affinity support for MSI interrupts. Since the parent interrupt affinity cannot be changed, affinity control for the child interrupt (MSI) is achieved by redirecting the handler to run in IRQ work context on the target CPU. This patch was originally prepared by Thomas Gleixner (see Link tag below) in a patch series that was never submitted as is, and only parts of that series have made it upstream so far. Originally-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Radu Rendec <rrendec@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/linux-pci/878qpg4o4t.ffs@tglx/ Link: https://patch.msgid.link/20251128212055.1409093-4-rrendec@redhat.com (cherry picked from commit eaf290c)
1 parent 7466bfc commit 553c3c3

1 file changed

Lines changed: 28 additions & 5 deletions

File tree

drivers/pci/controller/dwc/pcie-designware-host.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,27 @@ static struct pci_ops dw_pcie_ops;
2828
static struct pci_ops dw_pcie_ecam_ops;
2929
static struct pci_ops dw_child_pcie_ops;
3030

31+
#ifdef CONFIG_SMP
32+
static void dw_irq_noop(struct irq_data *d) { }
33+
#endif
34+
35+
static bool dw_pcie_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
36+
struct irq_domain *real_parent, struct msi_domain_info *info)
37+
{
38+
if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
39+
return false;
40+
41+
#ifdef CONFIG_SMP
42+
info->chip->irq_ack = dw_irq_noop;
43+
info->chip->irq_pre_redirect = irq_chip_pre_redirect_parent;
44+
#else
45+
info->chip->irq_ack = irq_chip_ack_parent;
46+
#endif
47+
return true;
48+
}
49+
3150
#define DW_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
3251
MSI_FLAG_USE_DEF_CHIP_OPS | \
33-
MSI_FLAG_NO_AFFINITY | \
3452
MSI_FLAG_PCI_MSI_MASK_PARENT)
3553
#define DW_PCIE_MSI_FLAGS_SUPPORTED (MSI_FLAG_MULTI_PCI_MSI | \
3654
MSI_FLAG_PCI_MSIX | \
@@ -42,9 +60,8 @@ static const struct msi_parent_ops dw_pcie_msi_parent_ops = {
4260
.required_flags = DW_PCIE_MSI_FLAGS_REQUIRED,
4361
.supported_flags = DW_PCIE_MSI_FLAGS_SUPPORTED,
4462
.bus_select_token = DOMAIN_BUS_PCI_MSI,
45-
.chip_flags = MSI_CHIP_FLAG_SET_ACK,
4663
.prefix = "DW-",
47-
.init_dev_msi_info = msi_lib_init_dev_msi_info,
64+
.init_dev_msi_info = dw_pcie_init_dev_msi_info,
4865
};
4966

5067
/* MSI int handler */
@@ -65,7 +82,7 @@ void dw_handle_msi_irq(struct dw_pcie_rp *pp)
6582
continue;
6683

6784
for_each_set_bit(pos, &status, MAX_MSI_IRQS_PER_CTRL)
68-
generic_handle_domain_irq(pp->irq_domain, irq_off + pos);
85+
generic_handle_demux_domain_irq(pp->irq_domain, irq_off + pos);
6986
}
7087
}
7188

@@ -142,10 +159,16 @@ static void dw_pci_bottom_ack(struct irq_data *d)
142159

143160
static struct irq_chip dw_pci_msi_bottom_irq_chip = {
144161
.name = "DWPCI-MSI",
145-
.irq_ack = dw_pci_bottom_ack,
146162
.irq_compose_msi_msg = dw_pci_setup_msi_msg,
147163
.irq_mask = dw_pci_bottom_mask,
148164
.irq_unmask = dw_pci_bottom_unmask,
165+
#ifdef CONFIG_SMP
166+
.irq_ack = dw_irq_noop,
167+
.irq_pre_redirect = dw_pci_bottom_ack,
168+
.irq_set_affinity = irq_chip_redirect_set_affinity,
169+
#else
170+
.irq_ack = dw_pci_bottom_ack,
171+
#endif
149172
};
150173

151174
static int dw_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,

0 commit comments

Comments
 (0)