From: Stanislav Spassov <stanspas@xxxxxxxxx> A broken device may never become responsive after reset, hence the need for a timeout. However, waiting for too long can have unintended side effects such as triggering hung task timeouts for processes waiting on a lock held during the reset. Locks that are shared across multiple devices, such as VFIO's per-bus reflck, are especially problematic, because a single broken VF can cause hangs for processes working with other VFs on the same bus. To allow lowering the global default post-reset timeout, while still accommodating devices that require more time, this patch introduces a per-device override that can be configured via a quirk. Signed-off-by: Stanislav Spassov <stanspas@xxxxxxxxx> --- drivers/pci/pci.c | 5 +---- drivers/pci/pci.h | 3 +++ drivers/pci/probe.c | 2 ++ include/linux/pci.h | 3 +++ 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5d62d4841d68..e81fd3b53bd0 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -157,9 +157,6 @@ static int __init pcie_port_pm_setup(char *str) } __setup("pcie_port_pm=", pcie_port_pm_setup); -/* Time to wait after a reset for device to become responsive */ -#define PCIE_RESET_READY_POLL_MS 60000 - /** * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children * @bus: pointer to PCI bus structure to search @@ -1033,7 +1030,7 @@ void pci_wakeup_bus(struct pci_bus *bus) static int pci_dev_wait(struct pci_dev *dev, enum pci_init_event event) { const char *event_name = pci_init_event_name(event); - int timeout = PCIE_RESET_READY_POLL_MS; + int timeout = dev->reset_ready_poll_ms; int delay = 1; u32 id; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 9b5dd6ea2f52..d8043d4dbe2f 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -113,6 +113,9 @@ int pci_bus_error_reset(struct pci_dev *dev); /* D0/D1->D2 and D2->D0 delay */ #define PCI_PM_D2_DELAY 200 +/* Time to wait after a reset for device to become responsive */ +#define PCIE_RESET_READY_POLL_MS 60000 + /** * struct pci_platform_pm_ops - Firmware PM callbacks * diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index eeff8a07f330..50b7219406ed 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2168,6 +2168,8 @@ struct pci_dev *pci_alloc_dev(struct pci_bus *bus) if (!dev) return NULL; + dev->reset_ready_poll_ms = PCIE_RESET_READY_POLL_MS; + INIT_LIST_HEAD(&dev->bus_list); dev->dev.type = &pci_dev_type; dev->bus = pci_bus_get(bus); diff --git a/include/linux/pci.h b/include/linux/pci.h index 1763e98625b9..978ede89741e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -392,6 +392,9 @@ struct pci_dev { unsigned int delay[PCI_INIT_EVENT_COUNT]; /* minimum waiting time after various events in ms */ + unsigned int reset_ready_poll_ms; /* Timeout for polling after + reset before the device is + deemed broken. */ #ifdef CONFIG_PCIEASPM struct pcie_link_state *link_state; /* ASPM link state */ -- 2.25.1 Amazon Development Center Germany GmbH Krausenstr. 38 10117 Berlin Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B Sitz: Berlin Ust-ID: DE 289 237 879