|
Jiri Slaby |
ef7db2 |
From: Lukas Wunner <lukas@wunner.de>
|
|
Jiri Slaby |
ef7db2 |
Date: Sun, 15 Jan 2023 09:20:33 +0100
|
|
Jiri Slaby |
ef7db2 |
Subject: [PATCH] PCI/DPC: Await readiness of secondary bus after reset
|
|
Jiri Slaby |
ef7db2 |
References: bsc#1012628
|
|
Jiri Slaby |
ef7db2 |
Patch-mainline: 6.2.3
|
|
Jiri Slaby |
ef7db2 |
Git-commit: 53b54ad074de1896f8b021615f65b27f557ce874
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
commit 53b54ad074de1896f8b021615f65b27f557ce874 upstream.
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
pci_bridge_wait_for_secondary_bus() is called after a Secondary Bus
|
|
Jiri Slaby |
ef7db2 |
Reset, but not after a DPC-induced Hot Reset.
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
As a result, the delays prescribed by PCIe r6.0 sec 6.6.1 are not
|
|
Jiri Slaby |
ef7db2 |
observed and devices on the secondary bus may be accessed before
|
|
Jiri Slaby |
ef7db2 |
they're ready.
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
One affected device is Intel's Ponte Vecchio HPC GPU. It comprises a
|
|
Jiri Slaby |
ef7db2 |
PCIe switch whose upstream port is not immediately ready after reset.
|
|
Jiri Slaby |
ef7db2 |
Because its config space is restored too early, it remains in
|
|
Jiri Slaby |
ef7db2 |
D0uninitialized, its subordinate devices remain inaccessible and DPC
|
|
Jiri Slaby |
ef7db2 |
recovery fails with messages such as:
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
i915 0000:8c:00.0: can't change power state from D3cold to D0 (config space inaccessible)
|
|
Jiri Slaby |
ef7db2 |
intel_vsec 0000:8e:00.1: can't change power state from D3cold to D0 (config space inaccessible)
|
|
Jiri Slaby |
ef7db2 |
pcieport 0000:89:02.0: AER: device recovery failed
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
Fix it.
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
Link: https://lore.kernel.org/r/9f5ff00e1593d8d9a4b452398b98aa14d23fca11.1673769517.git.lukas@wunner.de
|
|
Jiri Slaby |
ef7db2 |
Tested-by: Ravi Kishore Koppuravuri <ravi.kishore.koppuravuri@intel.com>
|
|
Jiri Slaby |
ef7db2 |
Signed-off-by: Lukas Wunner <lukas@wunner.de>
|
|
Jiri Slaby |
ef7db2 |
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
|
Jiri Slaby |
ef7db2 |
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
|
|
Jiri Slaby |
ef7db2 |
Cc: stable@vger.kernel.org
|
|
Jiri Slaby |
ef7db2 |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Jiri Slaby |
ef7db2 |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
ef7db2 |
---
|
|
Jiri Slaby |
ef7db2 |
drivers/pci/pci.c | 3 ---
|
|
Jiri Slaby |
ef7db2 |
drivers/pci/pci.h | 6 ++++++
|
|
Jiri Slaby |
ef7db2 |
drivers/pci/pcie/dpc.c | 4 ++--
|
|
Jiri Slaby |
ef7db2 |
3 files changed, 8 insertions(+), 5 deletions(-)
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
|
|
Jiri Slaby |
ef7db2 |
index 108c6ce5..da748247 100644
|
|
Jiri Slaby |
ef7db2 |
--- a/drivers/pci/pci.c
|
|
Jiri Slaby |
ef7db2 |
+++ b/drivers/pci/pci.c
|
|
Jiri Slaby |
ef7db2 |
@@ -167,9 +167,6 @@ static int __init pcie_port_pm_setup(char *str)
|
|
Jiri Slaby |
ef7db2 |
}
|
|
Jiri Slaby |
ef7db2 |
__setup("pcie_port_pm=", pcie_port_pm_setup);
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
-/* Time to wait after a reset for device to become responsive */
|
|
Jiri Slaby |
ef7db2 |
-#define PCIE_RESET_READY_POLL_MS 60000
|
|
Jiri Slaby |
ef7db2 |
-
|
|
Jiri Slaby |
ef7db2 |
/**
|
|
Jiri Slaby |
ef7db2 |
* pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
|
|
Jiri Slaby |
ef7db2 |
* @bus: pointer to PCI bus structure to search
|
|
Jiri Slaby |
ef7db2 |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
|
|
Jiri Slaby |
ef7db2 |
index 44643ffb..d2c08670 100644
|
|
Jiri Slaby |
ef7db2 |
--- a/drivers/pci/pci.h
|
|
Jiri Slaby |
ef7db2 |
+++ b/drivers/pci/pci.h
|
|
Jiri Slaby |
ef7db2 |
@@ -70,6 +70,12 @@ struct pci_cap_saved_state *pci_find_saved_ext_cap(struct pci_dev *dev,
|
|
Jiri Slaby |
ef7db2 |
* Reset (PCIe r6.0 sec 5.8).
|
|
Jiri Slaby |
ef7db2 |
*/
|
|
Jiri Slaby |
ef7db2 |
#define PCI_RESET_WAIT 1000 /* msec */
|
|
Jiri Slaby |
ef7db2 |
+/*
|
|
Jiri Slaby |
ef7db2 |
+ * Devices may extend the 1 sec period through Request Retry Status completions
|
|
Jiri Slaby |
ef7db2 |
+ * (PCIe r6.0 sec 2.3.1). The spec does not provide an upper limit, but 60 sec
|
|
Jiri Slaby |
ef7db2 |
+ * ought to be enough for any device to become responsive.
|
|
Jiri Slaby |
ef7db2 |
+ */
|
|
Jiri Slaby |
ef7db2 |
+#define PCIE_RESET_READY_POLL_MS 60000 /* msec */
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
void pci_update_current_state(struct pci_dev *dev, pci_power_t state);
|
|
Jiri Slaby |
ef7db2 |
void pci_refresh_power_state(struct pci_dev *dev);
|
|
Jiri Slaby |
ef7db2 |
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
|
|
Jiri Slaby |
ef7db2 |
index f5ffea17..a5d7c69b 100644
|
|
Jiri Slaby |
ef7db2 |
--- a/drivers/pci/pcie/dpc.c
|
|
Jiri Slaby |
ef7db2 |
+++ b/drivers/pci/pcie/dpc.c
|
|
Jiri Slaby |
ef7db2 |
@@ -170,8 +170,8 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
|
|
Jiri Slaby |
ef7db2 |
pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
|
|
Jiri Slaby |
ef7db2 |
PCI_EXP_DPC_STATUS_TRIGGER);
|
|
Jiri Slaby |
ef7db2 |
|
|
Jiri Slaby |
ef7db2 |
- if (!pcie_wait_for_link(pdev, true)) {
|
|
Jiri Slaby |
ef7db2 |
- pci_info(pdev, "Data Link Layer Link Active not set in 1000 msec\n");
|
|
Jiri Slaby |
ef7db2 |
+ if (pci_bridge_wait_for_secondary_bus(pdev, "DPC",
|
|
Jiri Slaby |
ef7db2 |
+ PCIE_RESET_READY_POLL_MS)) {
|
|
Jiri Slaby |
ef7db2 |
clear_bit(PCI_DPC_RECOVERED, &pdev->priv_flags);
|
|
Jiri Slaby |
ef7db2 |
ret = PCI_ERS_RESULT_DISCONNECT;
|
|
Jiri Slaby |
ef7db2 |
} else {
|
|
Jiri Slaby |
ef7db2 |
--
|
|
Jiri Slaby |
ef7db2 |
2.35.3
|
|
Jiri Slaby |
ef7db2 |
|