Hello Pawel Osciak, Justin Chuang, Vincent Palatin,
I'd like you to do a code review. Please visit
https://gerrit.chromium.org/gerrit/56555
to review the following change.
Change subject: CHROMIUM: usb: xhci: Use non-interruptible sleep for XHCI commands
......................................................................
CHROMIUM: usb: xhci: Use non-interruptible sleep for XHCI commands
The XHCI stack usually uses wait_for_completion_interruptible_timeout()
to wait for the completion of an XHCI command, and treats both timeouts
and interruptions as errors. This is a bad idea, since these commands
are often essential for the correct operation of the USB stack, and
their failure can leave devices in a misconfigured and/or unusable
state. While a timeout probably means a real problem that needs to be
dealt with, a random signal to the controlling user-space process should
not cause such harsh consequences.
This patch changes that behavior to use uninterruptible waits instead.
It fixes an easy to reproduce bug that occurs when you kill -9 a
process that reads from a UVC camera. The UVC driver's release code
tries to set the camera's alternate setting back to 0, but the lingering
SIGKILL instantly aborts any Stop Endpoint or Configure Endpoint command
sent to the xHC. The code dies halfway through the bandwidth allocation
process, leaving the device in an active configuration and preventing
future access to it due to the now out-of-sync bandwidth calculation.
This patch should be backported to kernels as far 2.6.31 that contain
the commit 3ffbba9511b4148cbe1f6b6238686adaeaca8feb "USB: xhci: Allocate
and address USB devices".
BUG=chrome-os-partner:19579
TEST=Do a cv2.VideoCapture(0).read() from python, then kill -9 the
python process. Make sure camera still works (on Spring or Stout).
Marking this CHROMIUM for now as it's needed to fix a factory test
problem, but I intend to upstream it immediately, too.
Change-Id: Idbef2ea30e20af854b73342a577c09757e7a542b
Signed-off-by: Julius Werner <
jwe...@chromium.org>
---
M drivers/usb/host/xhci-hub.c
M drivers/usb/host/xhci.c
2 files changed, 14 insertions(+), 19 deletions(-)
git pull ssh://
gerrit.chromium.org:29418/chromiumos/third_party/kernel refs/changes/55/56555/1
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index cc7e042..b2ad660 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -294,12 +294,11 @@
spin_unlock_irqrestore(&xhci->lock, flags);
/* Wait for last stop endpoint command to finish */
- timeleft = wait_for_completion_interruptible_timeout(
+ timeleft = wait_for_completion_timeout(
cmd->completion,
- USB_CTRL_SET_TIMEOUT);
+ XHCI_CMD_DEFAULT_TIMEOUT);
if (timeleft <= 0) {
- xhci_warn(xhci, "%s while waiting for stop endpoint command\n",
- timeleft == 0 ? "Timeout" : "Signal");
+ xhci_warn(xhci, "Timeout while waiting for Stop Endpoint\n");
spin_lock_irqsave(&xhci->lock, flags);
/* The timeout might have raced with the event ring handler, so
* only delete from the list if the item isn't poisoned.
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d62b429..ae7f1c6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -2474,15 +2474,14 @@
spin_unlock_irqrestore(&xhci->lock, flags);
/* Wait for the configure endpoint command to complete */
- timeleft = wait_for_completion_interruptible_timeout(
+ timeleft = wait_for_completion_timeout(
cmd_completion,
XHCI_CMD_DEFAULT_TIMEOUT);
if (timeleft <= 0) {
- xhci_warn(xhci, "%s while waiting for %s command\n",
- timeleft == 0 ? "Timeout" : "Signal",
+ xhci_warn(xhci, "Timeout while waiting for %s\n",
ctx_change == 0 ?
- "configure endpoint" :
- "evaluate context");
+ "Configure Endpoint" :
+ "Evaluate Context");
/* cancel the configure endpoint command */
ret = xhci_cancel_cmd(xhci, command, cmd_trb);
if (ret < 0)
@@ -3260,12 +3259,11 @@
spin_unlock_irqrestore(&xhci->lock, flags);
/* Wait for the Reset Device command to finish */
- timeleft = wait_for_completion_interruptible_timeout(
+ timeleft = wait_for_completion_timeout(
reset_device_cmd->completion,
- USB_CTRL_SET_TIMEOUT);
+ XHCI_CMD_DEFAULT_TIMEOUT);
if (timeleft <= 0) {
- xhci_warn(xhci, "%s while waiting for reset device command\n",
- timeleft == 0 ? "Timeout" : "Signal");
+ xhci_warn(xhci, "Timeout while waiting for Reset Device\n");
spin_lock_irqsave(&xhci->lock, flags);
/* The timeout might have raced with the event ring handler, so
* only delete from the list if the item isn't poisoned.
@@ -3449,11 +3447,10 @@
spin_unlock_irqrestore(&xhci->lock, flags);
/* XXX: how much time for xHC slot assignment? */
- timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
+ timeleft = wait_for_completion_timeout(&xhci->addr_dev,
XHCI_CMD_DEFAULT_TIMEOUT);
if (timeleft <= 0) {
- xhci_warn(xhci, "%s while waiting for a slot\n",
- timeleft == 0 ? "Timeout" : "Signal");
+ xhci_warn(xhci, "Timeout while waiting for a slot\n");
/* cancel the enable slot request */
return xhci_cancel_cmd(xhci, NULL, cmd_trb);
}
@@ -3567,15 +3564,14 @@
spin_unlock_irqrestore(&xhci->lock, flags);
/* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */
- timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
+ timeleft = wait_for_completion_timeout(&xhci->addr_dev,
XHCI_CMD_DEFAULT_TIMEOUT);
/* FIXME: From section 4.3.4: "Software shall be responsible for timing
* the SetAddress() "recovery interval" required by USB and aborting the
* command on a timeout.
*/
if (timeleft <= 0) {
- xhci_warn(xhci, "%s while waiting for address device command\n",
- timeleft == 0 ? "Timeout" : "Signal");
+ xhci_warn(xhci, "Timeout while waiting for Address Device\n");
/* cancel the address device command */
ret = xhci_cancel_cmd(xhci, NULL, cmd_trb);
if (ret < 0)
--
To view, visit
https://gerrit.chromium.org/gerrit/56555
To unsubscribe, visit
https://gerrit.chromium.org/gerrit/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Idbef2ea30e20af854b73342a577c09757e7a542b
Gerrit-PatchSet: 1
Gerrit-Project: chromiumos/third_party/kernel
Gerrit-Branch: chromeos-3.4
Gerrit-Owner: Julius Werner <
jwe...@chromium.org>
Gerrit-Reviewer: Justin Chuang <
jch...@chromium.org>
Gerrit-Reviewer: Pawel Osciak <
pos...@chromium.org>
Gerrit-Reviewer: Vincent Palatin <
vpal...@chromium.org>