diff mbox series

[2/2] PCI: Disable PCIE hotplug interrupts early when msi is disabled

Message ID 20250204053758.6025-2-feng.tang@linux.alibaba.com (mailing list archive)
State New
Headers show
Series [1/2] PCI/portdrv: Add necessary delay for disabling hotplug events | expand

Commit Message

Feng Tang Feb. 4, 2025, 5:37 a.m. UTC
There was a irq storm bug when testing "pci=nomsi" case, and the root
cause is: 'nomsi' will disable MSI and let devices and root ports use
legacy INTX inerrupt, and likely make several devices/ports share one
interrupt. In the failure case, BIOS doesn't disable the PCIE hotplug
interrupts, and  actually asserts the command-complete interrupt.
As MSI is disabled, ACPI initialization code will not enumerate root
port's PCIE hotplug capability, and pciehp service driver wont' be
enabled for the root port to handle that interrupt, later on when it is
shared and enabled by other device driver like NVME or NIC, the "nobody
care irq storm" happens.

So disable the pcie hotplug CCIE/HPIE interrupt in early boot phase when
MSI is not enbaled.

Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
---
 drivers/pci/probe.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Lukas Wunner Feb. 4, 2025, 9:14 a.m. UTC | #1
On Tue, Feb 04, 2025 at 01:37:58PM +0800, Feng Tang wrote:
> There was a irq storm bug when testing "pci=nomsi" case, and the root
> cause is: 'nomsi' will disable MSI and let devices and root ports use
> legacy INTX inerrupt, and likely make several devices/ports share one
> interrupt. In the failure case, BIOS doesn't disable the PCIE hotplug
> interrupts, and  actually asserts the command-complete interrupt.
> As MSI is disabled, ACPI initialization code will not enumerate root
> port's PCIE hotplug capability, and pciehp service driver wont' be
> enabled for the root port to handle that interrupt, later on when it is
> shared and enabled by other device driver like NVME or NIC, the "nobody
> care irq storm" happens.
> 
> So disable the pcie hotplug CCIE/HPIE interrupt in early boot phase when
> MSI is not enbaled.

So I think this issue should go away if disabling the interrupt
by portdrv is no longer conditional on

  (pcie_ports_native || host->native_pcie_hotplug)

like I've just proposed here:

  https://lore.kernel.org/r/Z6HYuBDP6uvE1Sf4@wunner.de/

... in which case this patch won't be necessary.  Can you confirm that?

You can split the change I've proposed into two patches if you like.

Thanks,

Lukas
Lukas Wunner Feb. 4, 2025, 9:23 a.m. UTC | #2
On Tue, Feb 04, 2025 at 01:37:58PM +0800, Feng Tang wrote:
> There was a irq storm bug when testing "pci=nomsi" case, and the root
> cause is: 'nomsi' will disable MSI and let devices and root ports use
> legacy INTX inerrupt, and likely make several devices/ports share one
> interrupt. In the failure case, BIOS doesn't disable the PCIE hotplug
> interrupts, and  actually asserts the command-complete interrupt.
> As MSI is disabled, ACPI initialization code will not enumerate root
> port's PCIE hotplug capability, and pciehp service driver wont' be
> enabled for the root port to handle that interrupt, later on when it is
> shared and enabled by other device driver like NVME or NIC, the "nobody
> care irq storm" happens.

Is there a section in the PCI Firmware Spec which says ACPI doesn't
enumerate the hotplug capability if MSI is disabled?

If so, it should be referenced in the commit message.

If not, I'm wondering if it's safe to fiddle with the Slot Control
register given the platform hasn't granted OSPM control of it.

Of course if this is spec-defined behavior in the nomsi case,
we could make the write to the Slot Control register conditional
on that.  But if this turns out to be platform-specific behavior,
we can't deal with it in generic PCI code but only in a quirk.

Thanks,

Lukas
Feng Tang Feb. 5, 2025, 3:58 a.m. UTC | #3
Hi Lukas,

On Tue, Feb 04, 2025 at 10:23:45AM +0100, Lukas Wunner wrote:
> On Tue, Feb 04, 2025 at 01:37:58PM +0800, Feng Tang wrote:
> > There was a irq storm bug when testing "pci=nomsi" case, and the root
> > cause is: 'nomsi' will disable MSI and let devices and root ports use
> > legacy INTX inerrupt, and likely make several devices/ports share one
> > interrupt. In the failure case, BIOS doesn't disable the PCIE hotplug
> > interrupts, and  actually asserts the command-complete interrupt.
> > As MSI is disabled, ACPI initialization code will not enumerate root
> > port's PCIE hotplug capability, and pciehp service driver wont' be
> > enabled for the root port to handle that interrupt, later on when it is
> > shared and enabled by other device driver like NVME or NIC, the "nobody
> > care irq storm" happens.
> 
> Is there a section in the PCI Firmware Spec which says ACPI doesn't
> enumerate the hotplug capability if MSI is disabled?

No, I didn't get it from spec, but found the logic by code reading
during debugging the irq storm issue. The related code is about:


#define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \
				| OSC_PCI_ASPM_SUPPORT \
				| OSC_PCI_CLOCK_PM_SUPPORT \
				| OSC_PCI_MSI_SUPPORT)

 acpi_pci_root_add
	negotiate_os_control
		calculate_support
			if (pci_msi_enabled())
				support |= OSC_PCI_MSI_SUPPORT;
		decode_osc_support
		os_control_query_checks
			if ((support & ACPI_PCIE_REQ_SUPPORT) != ACPI_PCIE_REQ_SUPPORT)
				return false
		acpi_pci_osc_control_set

And later in get_port_device_capability(), the pciehp service bit
won't be set, and driver is not loaded.

Thanks,
Feng

> If so, it should be referenced in the commit message.
> 
> If not, I'm wondering if it's safe to fiddle with the Slot Control
> register given the platform hasn't granted OSPM control of it.
> 
> Of course if this is spec-defined behavior in the nomsi case,
> we could make the write to the Slot Control register conditional
> on that.  But if this turns out to be platform-specific behavior,
> we can't deal with it in generic PCI code but only in a quirk.
> 
> Thanks,
> 
> Lukas
Feng Tang Feb. 5, 2025, 6:31 a.m. UTC | #4
On Tue, Feb 04, 2025 at 10:14:10AM +0100, Lukas Wunner wrote:
> On Tue, Feb 04, 2025 at 01:37:58PM +0800, Feng Tang wrote:
> > There was a irq storm bug when testing "pci=nomsi" case, and the root
> > cause is: 'nomsi' will disable MSI and let devices and root ports use
> > legacy INTX inerrupt, and likely make several devices/ports share one
> > interrupt. In the failure case, BIOS doesn't disable the PCIE hotplug
> > interrupts, and  actually asserts the command-complete interrupt.
> > As MSI is disabled, ACPI initialization code will not enumerate root
> > port's PCIE hotplug capability, and pciehp service driver wont' be
> > enabled for the root port to handle that interrupt, later on when it is
> > shared and enabled by other device driver like NVME or NIC, the "nobody
> > care irq storm" happens.
> > 
> > So disable the pcie hotplug CCIE/HPIE interrupt in early boot phase when
> > MSI is not enbaled.
> 
> So I think this issue should go away if disabling the interrupt
> by portdrv is no longer conditional on
> 
>   (pcie_ports_native || host->native_pcie_hotplug)
> 
> like I've just proposed here:
> 
>   https://lore.kernel.org/r/Z6HYuBDP6uvE1Sf4@wunner.de/
> 
> ... in which case this patch won't be necessary.  Can you confirm that?

Thanks for the suggestion! I will try to get the platform for test,
and report back.

As for the change, 
	 +		if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
	 +			pcie_capability_clear_word(dev, PCI_EXP_SLTCTL,
	 +				  PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);

The CONFIG_HOTPLUG_PCI_PCIE is always enabled on our platform and many
distros, I guess the check needs to be removed, which sees the 1 second
waiting again, and need the waiting logic in 1/2 patch?

Thanks,
Feng

> 
> You can split the change I've proposed into two patches if you like.
> 
> Thanks,
> 
> Lukas
diff mbox series

Patch

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b6536ed599c3..10d72156da9a 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1664,6 +1664,15 @@  void set_pcie_hotplug_bridge(struct pci_dev *pdev)
 	pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &reg32);
 	if (reg32 & PCI_EXP_SLTCAP_HPC)
 		pdev->is_hotplug_bridge = 1;
+
+	/*
+	 * When MSI is disabled, root port will use legacy INTX, and likely
+	 * share INTX interrupt line with other devices like NIC/NVME. There
+	 * was real world issue that the CCIE IRQ is asserted afer boot, but
+	 * will not be handled well and cause IRQ storm. So disable it early.
+	 */
+	if (!pci_msi_enabled())
+		pcie_disable_hp_interrupts_early(pdev);
 }
 
 static void set_pcie_thunderbolt(struct pci_dev *dev)