diff options
author | Marek Vasut <[email protected]> | 2024-07-23 15:27:01 +0200 |
---|---|---|
committer | Bjorn Helgaas <[email protected]> | 2024-07-29 12:46:35 -0500 |
commit | 5297bba507dc54045e6efeb9955c1271ca9aafe1 (patch) | |
tree | d5119434982d6502ccc6133596f567fa3dbbf573 | |
parent | 8400291e289ee6b2bf9779ff1c83a291501f017b (diff) |
genirq/msi: Silence 'set affinity failed' warning
Various PCI controllers that mux MSIs onto a single IRQ line produce these
"IRQ%d: set affinity failed" warnings when entering suspend. This has been
discussed before [1] [2] and an example test case is included at the end of
this commit message.
Controller drivers that create MSI IRQ domain with
MSI_FLAG_USE_DEF_CHIP_OPS and do not override the .irq_set_affinity()
irqchip callback get assigned the default msi_domain_set_affinity()
callback. That is not desired on controllers where it is not possible to
set affinity of each MSI IRQ line to a specific CPU core due to hardware
limitation.
Introduce flag MSI_FLAG_NO_AFFINITY, which keeps .irq_set_affinity() unset
if the controller driver did not assign it. This way, migrate_one_irq()
can exit right away, without printing the warning. The .irq_set_affinity()
implementations which only return -EINVAL can be removed from multiple
controller drivers.
$ grep 25 /proc/interrupts
25: 0 0 0 0 0 0 0 0 PCIe MSI 0 Edge PCIe PME
$ echo core > /sys/power/pm_test ; echo mem > /sys/power/state
...
Disabling non-boot CPUs ...
IRQ25: set affinity failed(-22). <---------- This is being silenced here
psci: CPU7 killed (polled 4 ms)
...
[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/all/[email protected]/
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Marek Vasut <[email protected]>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <[email protected]>
Reviewed-by: Damien Le Moal <[email protected]>
Reviewed-by: Manivannan Sadhasivam <[email protected]>
Acked-by: Thomas Gleixner <[email protected]>
-rw-r--r-- | include/linux/msi.h | 2 | ||||
-rw-r--r-- | kernel/irq/msi.c | 2 |
2 files changed, 3 insertions, 1 deletions
diff --git a/include/linux/msi.h b/include/linux/msi.h index 944979763825..b10093c4d00e 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -554,6 +554,8 @@ enum { MSI_FLAG_MSIX_CONTIGUOUS = (1 << 19), /* PCI/MSI-X vectors can be dynamically allocated/freed post MSI-X enable */ MSI_FLAG_PCI_MSIX_ALLOC_DYN = (1 << 20), + /* PCI MSIs cannot be steered separately to CPU cores */ + MSI_FLAG_NO_AFFINITY = (1 << 21), }; /** diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 5fa0547ece0c..ca6e2ae6d6fc 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -832,7 +832,7 @@ static void msi_domain_update_chip_ops(struct msi_domain_info *info) struct irq_chip *chip = info->chip; BUG_ON(!chip || !chip->irq_mask || !chip->irq_unmask); - if (!chip->irq_set_affinity) + if (!chip->irq_set_affinity && !(info->flags & MSI_FLAG_NO_AFFINITY)) chip->irq_set_affinity = msi_domain_set_affinity; } |