genirq/msi: Silence 'set affinity failed' warning
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Tue, 23 Jul 2024 13:27:01 +0000 (15:27 +0200)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 29 Jul 2024 17:46:35 +0000 (12:46 -0500)
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/d4a6eea3c5e33a3a4056885419df95a7@kernel.org/
[2] https://lore.kernel.org/all/5f4947b18bf381615a37aa81c2242477@kernel.org/

Link: https://lore.kernel.org/r/20240723132958.41320-2-marek.vasut+renesas@mailbox.org
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
include/linux/msi.h
kernel/irq/msi.c

index 944979763825569ca480a7634e3f087b41b89812..b10093c4d00ea5a2ce1c7ab10bab00a20bfca327 100644 (file)
@@ -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),
 };
 
 /**
index 5fa0547ece0c4d493f45821c9d062611232bda9a..ca6e2ae6d6fc0a11a5ef46af68ed9ce79d89eb9f 100644 (file)
@@ -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;
 }