Re: [PATCH v2] PCI: Avoid link retraining on empty ports when lifting speed restriction
"Maciej W. Rozycki" <[email protected]> Sat, 1 Aug 2026 16:14:05 +0100 (BST)
| Newsgroups | org.kernel.vger.linux-pci,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Sat, 1 Aug 2026, Andreas Wild wrote:
> Since commit 72780f796468 ("PCI: Always lift 2.5GT/s restriction in PCIe
> failed link retraining") the Target Speed quirk lifts a firmware-imposed
> 2.5GT/s restriction on any downstream port, without checking whether the
> link is up. Where nothing is plugged in, the retraining that follows can
> never complete, so each attempt costs PCIE_LINK_RETRAIN_TIMEOUT_MS. The
> quirk makes two of them -- the initial one and the restore on the error
> path -- adding a fixed 2 s to every boot.
>
> On an MSI PRO Z690-A WIFI DDR4 (Intel 600 Series PCH) with one empty x1
> slot, running v7.2-rc5:
>
> 0.541 pci 0000:00:1c.0: removing 2.5GT/s downstream link speed restriction
> 1.541 pci 0000:00:1c.0: retraining failed
> 2.541 pci 0000:00:1c.2: [8086:7aba] type 01 class 0x060400
>
> The kerneldoc above the quirk already contemplates this case ("For a port
> that has been left unconnected both bits will be clear") and describes
> lifting the restriction where firmware arranged it "and the port reports
> its link already being up". The code stopped checking the latter.
I think we need to just bail out early in this case. If a link has been
already clamped at 2.5GT/s and no link has been established, then there's
no point in going through the whole dance, just as already documented.
I.e. something like the change below. It works for me and if it does for
you too, then please feel free to use it as v3 with the change description
updated accordingly. Thank you for the report and the proposed fix.
Maciej
Signed-off-by: Maciej W. Rozycki <[email protected]>
---
drivers/pci/quirks.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
linux-pcie-failed-link-retrain-unclamp-always-fix.diff
Index: linux-macro/drivers/pci/quirks.c
===================================================================
--- linux-macro.orig/drivers/pci/quirks.c
+++ linux-macro/drivers/pci/quirks.c
@@ -108,7 +108,11 @@ int pcie_failed_link_retrain(struct pci_
pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &oldlnkctl2);
- if (!(lnksta & PCI_EXP_LNKSTA_DLLLA) && pcie_lbms_seen(dev, lnksta)) {
+ if (lnksta & PCI_EXP_LNKSTA_DLLLA) {
+ ;
+ } else if (PCIE_LNKCTL2_TLS2SPEED(oldlnkctl2) == PCIE_SPEED_2_5GT) {
+ return ret;
+ } else if (pcie_lbms_seen(dev, lnksta)) {
pci_info(dev, "broken device, retraining non-functional downstream link at 2.5GT/s\n");
ret = pcie_set_target_speed(dev, PCIE_SPEED_2_5GT, false);
if (ret)