]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Apr 2018 07:09:59 +0000 (09:09 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Apr 2018 07:09:59 +0000 (09:09 +0200)
added patches:
pci-wait-up-to-60-seconds-for-device-to-become-ready-after-flr.patch

queue-4.9/pci-wait-up-to-60-seconds-for-device-to-become-ready-after-flr.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/pci-wait-up-to-60-seconds-for-device-to-become-ready-after-flr.patch b/queue-4.9/pci-wait-up-to-60-seconds-for-device-to-become-ready-after-flr.patch
new file mode 100644 (file)
index 0000000..fa143c7
--- /dev/null
@@ -0,0 +1,106 @@
+From 821cdad5c46cae94ce65b9a98614c70a6ff021f8 Mon Sep 17 00:00:00 2001
+From: Sinan Kaya <okaya@codeaurora.org>
+Date: Tue, 29 Aug 2017 14:45:45 -0500
+Subject: PCI: Wait up to 60 seconds for device to become ready after FLR
+
+From: Sinan Kaya <okaya@codeaurora.org>
+
+commit 821cdad5c46cae94ce65b9a98614c70a6ff021f8 upstream.
+
+Sporadic reset issues have been observed with an Intel 750 NVMe drive while
+assigning the physical function to the guest machine.  The sequence of
+events observed is as follows:
+
+  - perform a Function Level Reset (FLR)
+  - sleep up to 1000ms total
+  - read ~0 from PCI_COMMAND (CRS completion for config read)
+  - warn that the device didn't return from FLR
+  - touch the device before it's ready
+  - device drops config writes when we restore register settings (there's
+    no mechanism for software to learn about CRS completions for writes)
+  - incomplete register restore leaves device in inconsistent state
+  - device probe fails because device is in inconsistent state
+
+After reset, an endpoint may respond to config requests with Configuration
+Request Retry Status (CRS) to indicate that it is not ready to accept new
+requests. See PCIe r3.1, sec 2.3.1 and 6.6.2.
+
+Increase the timeout value from 1 second to 60 seconds to cover the period
+where device responds with CRS and also report polling progress.
+
+Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
+[bhelgaas: include the mandatory 100ms in the delays we print]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/pci.c |   52 +++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 37 insertions(+), 15 deletions(-)
+
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -3756,27 +3756,49 @@ int pci_wait_for_pending_transaction(str
+ }
+ EXPORT_SYMBOL(pci_wait_for_pending_transaction);
+-/*
+- * We should only need to wait 100ms after FLR, but some devices take longer.
+- * Wait for up to 1000ms for config space to return something other than -1.
+- * Intel IGD requires this when an LCD panel is attached.  We read the 2nd
+- * dword because VFs don't implement the 1st dword.
+- */
+ static void pci_flr_wait(struct pci_dev *dev)
+ {
+-      int i = 0;
++      int delay = 1, timeout = 60000;
+       u32 id;
+-      do {
+-              msleep(100);
++      /*
++       * Per PCIe r3.1, sec 6.6.2, a device must complete an FLR within
++       * 100ms, but may silently discard requests while the FLR is in
++       * progress.  Wait 100ms before trying to access the device.
++       */
++      msleep(100);
++
++      /*
++       * After 100ms, the device should not silently discard config
++       * requests, but it may still indicate that it needs more time by
++       * responding to them with CRS completions.  The Root Port will
++       * generally synthesize ~0 data to complete the read (except when
++       * CRS SV is enabled and the read was for the Vendor ID; in that
++       * case it synthesizes 0x0001 data).
++       *
++       * Wait for the device to return a non-CRS completion.  Read the
++       * Command register instead of Vendor ID so we don't have to
++       * contend with the CRS SV value.
++       */
++      pci_read_config_dword(dev, PCI_COMMAND, &id);
++      while (id == ~0) {
++              if (delay > timeout) {
++                      dev_warn(&dev->dev, "not ready %dms after FLR; giving up\n",
++                               100 + delay - 1);
++                      return;
++              }
++
++              if (delay > 1000)
++                      dev_info(&dev->dev, "not ready %dms after FLR; waiting\n",
++                               100 + delay - 1);
++
++              msleep(delay);
++              delay *= 2;
+               pci_read_config_dword(dev, PCI_COMMAND, &id);
+-      } while (i++ < 10 && id == ~0);
++      }
+-      if (id == ~0)
+-              dev_warn(&dev->dev, "Failed to return from FLR\n");
+-      else if (i > 1)
+-              dev_info(&dev->dev, "Required additional %dms to return from FLR\n",
+-                       (i - 1) * 100);
++      if (delay > 1000)
++              dev_info(&dev->dev, "ready %dms after FLR\n", 100 + delay - 1);
+ }
+ static int pcie_flr(struct pci_dev *dev, int probe)
index ad5e33deae708ed5272c4599a798da62d88c8968..52ef1fb99399cf542fa2a85324640e84660b3868 100644 (file)
@@ -24,3 +24,4 @@ mac80211_hwsim-fix-use-after-free-bug-in-hwsim_exit_net.patch
 r8152-add-linksys-usb3gigv1-id.patch
 revert-pinctrl-intel-initialize-gpio-properly-when-used-through-irqchip.patch
 revert-ath10k-send-re-assoc-peer-command-when-nss-changed.patch
+pci-wait-up-to-60-seconds-for-device-to-become-ready-after-flr.patch