Skip to content

Commit f09c1d6

Browse files
Marc ZyngierKAGA-KOKO
authored andcommitted
irqchip/msi-lib: Honor the MSI_FLAG_PCI_MSI_MASK_PARENT flag
For systems that implement interrupt masking at the interrupt controller level, the MSI library offers MSI_FLAG_PCI_MSI_MASK_PARENT. It indicates that it isn't enough to only unmask the interrupt at the PCI device level, but that the interrupt controller must also be involved. However, the way this is currently done is less than optimal, as the masking/unmasking is done on both sides, always. It would be far cheaper to unmask both at the start of times, and then only deal with the interrupt controller mask, which is cheaper than a round-trip to the PCI endpoint. Now that the PCI/MSI layer implements irq_startup() and irq_shutdown() callbacks, which [un]mask at the PCI level and honor the request to [un]mask the parent, this can be trivially done. Overwrite the irq_mask/unmask() callbacks of the device domain interrupt chip with irq_[un]mask_parent() when the parent domain asks for it. [ tglx: Adopted to the PCI/MSI changes ] Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Marc Zyngier <maz@kernel.org> Acked-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/all/20250903135433.380783272@linutronix.de
1 parent b2a0c13 commit f09c1d6

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

drivers/irqchip/irq-msi-lib.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,20 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
112112
*/
113113
if (!chip->irq_set_affinity && !(info->flags & MSI_FLAG_NO_AFFINITY))
114114
chip->irq_set_affinity = msi_domain_set_affinity;
115+
116+
/*
117+
* If the parent domain insists on being in charge of masking, obey
118+
* blindly. The interrupt is un-masked at the PCI level on startup
119+
* and masked on shutdown to prevent rogue interrupts after the
120+
* driver freed the interrupt. Not masking it at the PCI level
121+
* speeds up operation for disable/enable_irq() as it avoids
122+
* getting all the way out to the PCI device.
123+
*/
124+
if (info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT) {
125+
chip->irq_mask = irq_chip_mask_parent;
126+
chip->irq_unmask = irq_chip_unmask_parent;
127+
}
128+
115129
return true;
116130
}
117131
EXPORT_SYMBOL_GPL(msi_lib_init_dev_msi_info);

0 commit comments

Comments
 (0)