From: Mika Westerberg <mika.westerberg@linux.intel.com>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: Mahesh J Salgaonkar <mahesh@linux.ibm.com>,
oohall@gmail.com, Lukas Wunner <lukas@wunner.de>,
Chris Chiu <chris.chiu@canonical.com>,
Sathyanarayanan Kuppuswamy
<sathyanarayanan.kuppuswamy@linux.intel.com>,
Ashok Raj <ashok.raj@intel.com>,
Sheng Bi <windy.bi.enflame@gmail.com>,
Ravi Kishore Koppuravuri <ravi.kishore.koppuravuri@intel.com>,
Stanislav Spassov <stanspas@amazon.de>,
Yang Su <yang.su@linux.alibaba.com>,
shuo.tan@linux.alibaba.com,
Mika Westerberg <mika.westerberg@linux.intel.com>,
linux-pci@vger.kernel.org
Subject: [PATCH v4] PCI/PM: Shorten pci_bridge_wait_for_secondary_bus() wait time for slow links
Date: Tue, 18 Apr 2023 10:28:08 +0300 [thread overview]
Message-ID: <20230418072808.10431-1-mika.westerberg@linux.intel.com> (raw)
With slow links (<= 5GT/s) active link reporting is not mandatory, so if
a device is disconnected during system sleep we might end up waiting for
it to respond for ~60s slowing down resume time. PCIe spec r6.0 sec
6.6.1 mandates that the system software must wait for at least 1s before
it can determine the device as brokine device so use the minimum
requirement for slow links. In addition if the port supports active link
reporting we check if the link is trained before starting to wait.
This should make system resume time faster for slow links as well while
still following the PCIe spec.
While there move the PCI_RESET_WAIT constant into pci.c because it is
not used outside of that file anymore.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
Hi all,
Here is the fourth version of the patch. Hopefully I did not miss
anything this time ;-)
This applies on top of
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/log/?h=reset
Changes since the previous version:
* Added back the comment change that was missed
* Use PCI_RESET_WAIT - delay for the slow link timeout
* Check active link reporting support in the slow link path
The previous version of the patch can be found:
https://lore.kernel.org/linux-pci/20230413101642.8724-1-mika.westerberg@linux.intel.com/
drivers/pci/pci.c | 44 ++++++++++++++++++++++++++++++++------------
drivers/pci/pci.h | 7 -------
2 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0b4f3b08f780..a40234c9f7a4 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -64,6 +64,13 @@ struct pci_pme_device {
#define PME_TIMEOUT 1000 /* How long between PME checks */
+/*
+ * Following exit from Conventional Reset, devices must be ready within 1 sec
+ * (PCIe r6.0 sec 6.6.1). A D3cold to D0 transition implies a Conventional
+ * Reset (PCIe r6.0 sec 5.8).
+ */
+#define PCI_RESET_WAIT 1000 /* msec */
+
/*
* Devices may extend the 1 sec period through Request Retry Status
* completions (PCIe r6.0 sec 2.3.1). The spec does not provide an upper
@@ -5012,11 +5019,9 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
*
* However, 100 ms is the minimum and the PCIe spec says the
* software must allow at least 1s before it can determine that the
- * device that did not respond is a broken device. There is
- * evidence that 100 ms is not always enough, for example certain
- * Titan Ridge xHCI controller does not always respond to
- * configuration requests if we only wait for 100 ms (see
- * https://bugzilla.kernel.org/show_bug.cgi?id=203885).
+ * device that did not respond is a broken device. Also device can
+ * take longer than that to respond if it indicates so through Request
+ * Retry Status completions.
*
* Therefore we wait for 100 ms and check for the device presence
* until the timeout expires.
@@ -5027,14 +5032,29 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) {
pci_dbg(dev, "waiting %d ms for downstream link\n", delay);
msleep(delay);
- } else {
- pci_dbg(dev, "waiting %d ms for downstream link, after activation\n",
- delay);
- if (!pcie_wait_for_link_delay(dev, true, delay)) {
- /* Did not train, no need to wait any further */
- pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n");
- return -ENOTTY;
+
+ /*
+ * If the port supports active link reporting we now check
+ * whether the link is active and if not bail out early with
+ * the assumption that the device is not present anymore.
+ */
+ if (dev->link_active_reporting) {
+ u16 status;
+
+ pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &status);
+ if (!(status & PCI_EXP_LNKSTA_DLLLA))
+ return -ENOTTY;
}
+
+ return pci_dev_wait(child, reset_type, PCI_RESET_WAIT - delay);
+ }
+
+ pci_dbg(dev, "waiting %d ms for downstream link, after activation\n",
+ delay);
+ if (!pcie_wait_for_link_delay(dev, true, delay)) {
+ /* Did not train, no need to wait any further */
+ pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n");
+ return -ENOTTY;
}
return pci_dev_wait(child, reset_type,
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 022da58afb33..f2d3aeab91f4 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -64,13 +64,6 @@ struct pci_cap_saved_state *pci_find_saved_ext_cap(struct pci_dev *dev,
#define PCI_PM_D3HOT_WAIT 10 /* msec */
#define PCI_PM_D3COLD_WAIT 100 /* msec */
-/*
- * Following exit from Conventional Reset, devices must be ready within 1 sec
- * (PCIe r6.0 sec 6.6.1). A D3cold to D0 transition implies a Conventional
- * Reset (PCIe r6.0 sec 5.8).
- */
-#define PCI_RESET_WAIT 1000 /* msec */
-
void pci_update_current_state(struct pci_dev *dev, pci_power_t state);
void pci_refresh_power_state(struct pci_dev *dev);
int pci_power_up(struct pci_dev *dev);
--
2.39.2
next reply other threads:[~2023-04-18 7:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-18 7:28 Mika Westerberg [this message]
2023-04-21 20:51 ` [PATCH v4] PCI/PM: Shorten pci_bridge_wait_for_secondary_bus() wait time for slow links Lukas Wunner
2023-04-24 6:00 ` Mika Westerberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230418072808.10431-1-mika.westerberg@linux.intel.com \
--to=mika.westerberg@linux.intel.com \
--cc=ashok.raj@intel.com \
--cc=bhelgaas@google.com \
--cc=chris.chiu@canonical.com \
--cc=linux-pci@vger.kernel.org \
--cc=lukas@wunner.de \
--cc=mahesh@linux.ibm.com \
--cc=oohall@gmail.com \
--cc=ravi.kishore.koppuravuri@intel.com \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=shuo.tan@linux.alibaba.com \
--cc=stanspas@amazon.de \
--cc=windy.bi.enflame@gmail.com \
--cc=yang.su@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox