Thread (28 messages) 28 messages, 9 authors, 2025-07-09

Re: [PATCH v4 4/5] PCI: host-common: Add link down handling for host bridges

From: Manivannan Sadhasivam <hidden>
Date: 2025-05-14 16:33:19
Also in: linux-arm-kernel, linux-arm-msm, linux-pci, linux-riscv, lkml

On Wed, May 14, 2025 at 12:00:11PM +0530, Krishna Chaitanya Chundru wrote:

On 5/8/2025 12:40 PM, Manivannan Sadhasivam wrote:
quoted
The PCI link, when down, needs to be recovered to bring it back. But that
cannot be done in a generic way as link recovery procedure is specific to
host bridges. So add a new API pci_host_handle_link_down() that could be
called by the host bridge drivers when the link goes down.

The API will iterate through all the slots and calls the pcie_do_recovery()
function with 'pci_channel_io_frozen' as the state. This will result in the
execution of the AER Fatal error handling code. Since the link down
recovery is pretty much the same as AER Fatal error handling,
pcie_do_recovery() helper is reused here. First the AER error_detected
callback will be triggered for the bridge and the downstream devices. Then,
pci_host_reset_slot() will be called for the slot, which will reset the
slot using 'reset_slot' callback to recover the link. Once that's done,
resume message will be broadcasted to the bridge and the downstream devices
indicating successful link recovery.

In case if the AER support is not enabled in the kernel, only
pci_bus_error_reset() will be called for each slots as there is no way we
could inform the drivers about link recovery.

Signed-off-by: Manivannan Sadhasivam <redacted>
---
  drivers/pci/controller/pci-host-common.c | 58 ++++++++++++++++++++++++++++++++
  drivers/pci/controller/pci-host-common.h |  1 +
  drivers/pci/pci.c                        |  1 +
  drivers/pci/pcie/err.c                   |  1 +
  4 files changed, 61 insertions(+)
diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index f93bc7034e697250711833a5151f7ef177cd62a0..f916f0a874a61ddfbfd99f96975c00fb66dd224c 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -12,9 +12,11 @@
  #include <linux/of.h>
  #include <linux/of_address.h>
  #include <linux/of_pci.h>
+#include <linux/pci.h>
  #include <linux/pci-ecam.h>
  #include <linux/platform_device.h>
+#include "../pci.h"
  #include "pci-host-common.h"
  static void gen_pci_unmap_cfg(void *ptr)
@@ -96,5 +98,61 @@ void pci_host_common_remove(struct platform_device *pdev)
  }
  EXPORT_SYMBOL_GPL(pci_host_common_remove);
+#if IS_ENABLED(CONFIG_PCIEAER)
+static pci_ers_result_t pci_host_reset_slot(struct pci_dev *dev)
+{
+	int ret;
+
+	ret = pci_bus_error_reset(dev);
+	if (ret) {
+		pci_err(dev, "Failed to reset slot: %d\n", ret);
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+
+	pci_info(dev, "Slot has been reset\n");
+
+	return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void pci_host_recover_slots(struct pci_host_bridge *host)
+{
+	struct pci_bus *bus = host->bus;
+	struct pci_dev *dev;
+
+	for_each_pci_bridge(dev, bus) {
+		if (!pci_is_root_bus(bus))
bus here is always constant here, we may need to have check
for dev here like if (!pci_is_root_bus(dev->bus))
Good catch! Ammended it while applying.

- Mani

-- 
மணிவண்ணன் சதாசிவம்
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help