From: Jinhui Guo <guojinhui.liam@bytedance.com> maillist inclusion category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/13837 Reference: https://lore.kernel.org/all/20241107143758.12643-1-guojinhui.liam@bytedance.... ------------------------------------------- During extreme hotplug stress tests (e.g., NVMe insertions 50 times), the link speed is permanently downgraded to 2.5 GT/s. "Card present" is reported twice via external interrupts due to a slight tremor when the NVMe device is plugged in. The failure of the link activation for the first time leads to the link speed of the root port being mistakenly downgraded to 2.5GT/s by the ASMedia workaround. If the link subsequently trains successfully at 2.5GT/s, the device gets trapped at Gen1 speed because the recovery logic only applies to ASMedia chips. Upstream community addressed this by relying on the newly introduced pci/bwctrl subsystem (Commit de9a6c8d5dbf), which is not present in stable kernels like 6.6. Backporting the mainline fix would require pulling in massive architectural changes and risking system stability. This patch adopts the RFC approach to avoid wrongly setting the link speed to 2.5GT/s by moving the whitelist check to the very beginning. Only allow the specific ASMedia PCIe switches to perform link retrain. Fixes: a89c82249c37 ("PCI: Work around PCIe link training failures") Signed-off-by: Jinhui Guo <guojinhui.liam@bytedance.com> Signed-off-by: Zhang Hongtao <zhanghongtao35@huawei.com> --- drivers/pci/quirks.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a2a2bde69a026..fbdd54cc81c71 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -94,7 +94,8 @@ int pcie_failed_link_retrain(struct pci_dev *dev) int ret = -ENOTTY; if (!pci_is_pcie(dev) || !pcie_downstream_port(dev) || - !pcie_cap_has_lnkctl2(dev) || !dev->link_active_reporting) + !pcie_cap_has_lnkctl2(dev) || !dev->link_active_reporting || + !pci_match_id(ids, dev)) return ret; pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &lnkctl2); @@ -122,8 +123,7 @@ int pcie_failed_link_retrain(struct pci_dev *dev) } if ((lnksta & PCI_EXP_LNKSTA_DLLLA) && - (lnkctl2 & PCI_EXP_LNKCTL2_TLS) == PCI_EXP_LNKCTL2_TLS_2_5GT && - pci_match_id(ids, dev)) { + (lnkctl2 & PCI_EXP_LNKCTL2_TLS) == PCI_EXP_LNKCTL2_TLS_2_5GT) { u32 lnkcap; pci_info(dev, "removing 2.5GT/s downstream link speed restriction\n"); -- 2.43.0