From: Greg Kroah-Hartman Date: Thu, 29 Jun 2017 12:15:45 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v3.18.60~65 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5de911219bf83e92cf44d60f686ea692219a1b31;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: xhci-fix-deadlock-at-host-remove-by-running-watchdog-correctly.patch --- diff --git a/queue-3.18/series b/queue-3.18/series new file mode 100644 index 00000000000..37db7bb2138 --- /dev/null +++ b/queue-3.18/series @@ -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 index 00000000000..a18e36e7763 --- /dev/null +++ b/queue-3.18/xhci-fix-deadlock-at-host-remove-by-running-watchdog-correctly.patch @@ -0,0 +1,82 @@ +From d6169d04097fd9ddf811e63eae4e5cd71e6666e2 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Wed, 11 Jan 2017 17:10:34 +0200 +Subject: xhci: fix deadlock at host remove by running watchdog correctly + +From: Mathias Nyman + +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 +Signed-off-by: Howard Yen +Signed-off-by: Greg Kroah-Hartman + +--- + 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];