Patch "PCI: Wait for Link Training==0 before starting Link retrain" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    PCI: Wait for Link Training==0 before starting Link retrain

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pci-wait-for-link-training-0-before-starting-link-re.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 07faec99bd306a67ff17c8013d46e0d1da15ab88
Author: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx>
Date:   Tue Apr 23 16:08:19 2024 +0300

    PCI: Wait for Link Training==0 before starting Link retrain
    
    [ Upstream commit 73cb3a35f94db723c0211ad099bce55b2155e3f0 ]
    
    Two changes were made in link retraining logic independent of each other.
    
    The commit e7e39756363a ("PCI/ASPM: Avoid link retraining race") added a
    check to pcie_retrain_link() to ensure no Link Training is currently active
    to address the Implementation Note in PCIe r6.1 sec 7.5.3.7. At that time
    pcie_wait_for_retrain() only checked for the Link Training (LT) bit being
    cleared.
    
    The commit 680e9c47a229 ("PCI: Add support for polling DLLLA to
    pcie_retrain_link()") generalized pcie_wait_for_retrain() into
    pcie_wait_for_link_status() which can wait either for LT or the Data Link
    Layer Link Active (DLLLA) bit with 'use_lt' argument and supporting waiting
    for either cleared or set using 'active' argument.
    
    In the merge commit 1abb47390350 ("Merge branch 'pci/enumeration'"), those
    two divergent branches converged. The merge changed LT bit checking added
    in the commit e7e39756363a ("PCI/ASPM: Avoid link retraining race") to now
    wait for completion of any ongoing Link Training using DLLLA bit being set
    if 'use_lt' is false.
    
    When 'use_lt' is false, the pseudo-code steps of what occurs in
    pcie_retrain_link():
    
            1. Wait for DLLLA==1
            2. Trigger link to retrain
            3. Wait for DLLLA==1
    
    Step 3 waits for the link to come up from the retraining triggered by Step
    2. As Step 1 is supposed to wait for any ongoing retraining to end, using
    DLLLA also for it does not make sense because link training being active is
    still indicated using LT bit, not with DLLLA.
    
    Correct the pcie_wait_for_link_status() parameters in Step 1 to only wait
    for LT==0 to ensure there is no ongoing Link Training.
    
    This only impacts the Target Speed quirk, which is the only case where
    waiting for DLLLA bit is used. It currently works in the problematic case
    by means of link training getting initiated by hardware repeatedly and
    respecting the new link parameters set by the caller, which then make
    training succeed and bring the link up, setting DLLLA and causing
    pcie_wait_for_link_status() to return success. We are not supposed to rely
    on luck and need to make sure that LT transitioned through the inactive
    state though before we initiate link training by hand via RL (Retrain Link)
    bit.
    
    Fixes: 1abb47390350 ("Merge branch 'pci/enumeration'")
    Link: https://lore.kernel.org/r/20240423130820.43824-1-ilpo.jarvinen@xxxxxxxxxxxxxxx
    Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx>
    Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index dddd30deea32b..6ea01007031a4 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4986,7 +4986,7 @@ int pcie_retrain_link(struct pci_dev *pdev, bool use_lt)
 	 * avoid LTSSM race as recommended in Implementation Note at the
 	 * end of PCIe r6.0.1 sec 7.5.3.7.
 	 */
-	rc = pcie_wait_for_link_status(pdev, use_lt, !use_lt);
+	rc = pcie_wait_for_link_status(pdev, true, false);
 	if (rc)
 		return rc;
 




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux