]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Jun 2017 12:15:45 +0000 (14:15 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Jun 2017 12:15:45 +0000 (14:15 +0200)
added patches:
xhci-fix-deadlock-at-host-remove-by-running-watchdog-correctly.patch

queue-3.18/series [new file with mode: 0644]
queue-3.18/xhci-fix-deadlock-at-host-remove-by-running-watchdog-correctly.patch [new file with mode: 0644]

diff --git a/queue-3.18/series b/queue-3.18/series
new file mode 100644 (file)
index 0000000..37db7bb
--- /dev/null
@@ -0,0 +1 @@
+xhci-fix-deadlock-at-host-remove-by-running-watchdog-correctly.patch
diff --git a/queue-3.18/xhci-fix-deadlock-at-host-remove-by-running-watchdog-correctly.patch b/queue-3.18/xhci-fix-deadlock-at-host-remove-by-running-watchdog-correctly.patch
new file mode 100644 (file)
index 0000000..a18e36e
--- /dev/null
@@ -0,0 +1,82 @@
+From d6169d04097fd9ddf811e63eae4e5cd71e6666e2 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Wed, 11 Jan 2017 17:10:34 +0200
+Subject: xhci: fix deadlock at host remove by running watchdog correctly
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit d6169d04097fd9ddf811e63eae4e5cd71e6666e2 upstream.
+
+If a URB is killed while the host is removed we can end up in a situation
+where the hub thread takes the roothub device lock, and waits for
+the URB to be given back by xhci-hcd, blocking the host remove code.
+
+xhci-hcd tries to stop the endpoint and give back the urb, but can't
+as the host is removed from PCI bus at the same time, preventing the normal
+way of giving back urb.
+
+Instead we need to rely on the stop command timeout function to give back
+the urb. This xhci_stop_endpoint_command_watchdog() timeout function
+used a XHCI_STATE_DYING flag to indicate if the timeout function is already
+running, but later this flag has been taking into use in other places to
+mark that xhci is dying.
+
+Remove checks for XHCI_STATE_DYING in xhci_urb_dequeue. We are still
+checking that reading from pci state does not return 0xffffffff or that
+host is not halted before trying to stop the endpoint.
+
+This whole area of stopping endpoints, giving back URBs, and the wathdog
+timeout need rework, this fix focuses on solving a specific deadlock
+issue that we can then send to stable before any major rework.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Howard Yen <howard_yen@htc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |   11 -----------
+ drivers/usb/host/xhci.c      |   13 -------------
+ 2 files changed, 24 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -839,17 +839,6 @@ void xhci_stop_endpoint_command_watchdog
+       spin_lock_irqsave(&xhci->lock, flags);
+       ep->stop_cmds_pending--;
+-      if (xhci->xhc_state & XHCI_STATE_REMOVING) {
+-              spin_unlock_irqrestore(&xhci->lock, flags);
+-              return;
+-      }
+-      if (xhci->xhc_state & XHCI_STATE_DYING) {
+-              xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
+-                              "Stop EP timer ran, but another timer marked "
+-                              "xHCI as DYING, exiting.");
+-              spin_unlock_irqrestore(&xhci->lock, flags);
+-              return;
+-      }
+       if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {
+               xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
+                               "Stop EP timer ran, but no command pending, "
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1565,19 +1565,6 @@ int xhci_urb_dequeue(struct usb_hcd *hcd
+               xhci_urb_free_priv(xhci, urb_priv);
+               return ret;
+       }
+-      if ((xhci->xhc_state & XHCI_STATE_DYING) ||
+-                      (xhci->xhc_state & XHCI_STATE_HALTED)) {
+-              xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
+-                              "Ep 0x%x: URB %p to be canceled on "
+-                              "non-responsive xHCI host.",
+-                              urb->ep->desc.bEndpointAddress, urb);
+-              /* Let the stop endpoint command watchdog timer (which set this
+-               * state) finish cleaning up the endpoint TD lists.  We must
+-               * have caught it in the middle of dropping a lock and giving
+-               * back an URB.
+-               */
+-              goto done;
+-      }
+       ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+       ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index];