linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] xhci: clear port_remote_wakeup after resume failure
@ 2019-07-02 11:12 Nicolas Saenz Julienne
  0 siblings, 0 replies; only message in thread
From: Nicolas Saenz Julienne @ 2019-07-02 11:12 UTC (permalink / raw)
  To: Mathias Nyman
  Cc: oneukum, Nicolas Saenz Julienne, Greg Kroah-Hartman, linux-usb,
	linux-kernel

This was seen on a Dell Precision 5520 using it's WD15 dock. The dock's
Ethernet connectivity is provided though USB. While idle, both the
Ethernet device and XHCI are suspended by runtime PM. To be then resumed
on behalf of the Ethernet device, which has remote wake-up capabilities.

The Ethernet device was observed to randomly disconnect from the USB
port shortly after submitting it's remote wake-up request. Probably a
weird timing issue yet to be investigated. This causes runtime PM to
busyloop causing some tangible CPU load. The reason is the port gets
stuck in the middle of a remote wake-up operation, waiting for the
device to switch to U0. This never happens, leaving "port_remote_wakeup"
enabled, and automatically triggering a failure on any further suspend
operation.

This patch clears "port_remote_wakeup" upon detecting a device with a
wrong PORT_CONNECT state. Making sure the above mentioned situation
doesn't trigger a PM busyloop.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---

Changes since v1:
  - Do not trigger clear based on PLS_MASK != XDEV_RESUME to avoid a
    potential race condition between the irq handler and hub thread.

 drivers/usb/host/xhci-hub.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 3abe70ff1b1e..05cd46a11c0c 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1047,8 +1047,8 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
 		xhci_get_usb2_port_status(port, &status, raw_port_status,
 					  flags);
 	/*
-	 * Clear stale usb2 resume signalling variables in case port changed
-	 * state during resume signalling. For example on error
+	 * Clear stale resume signalling variables in case port changed
+	 * state during resume signalling. For example on error.
 	 */
 	if ((bus_state->resume_done[wIndex] ||
 	     test_bit(wIndex, &bus_state->resuming_ports)) &&
@@ -1057,6 +1057,9 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
 		bus_state->resume_done[wIndex] = 0;
 		clear_bit(wIndex, &bus_state->resuming_ports);
 		usb_hcd_end_port_resume(&hcd->self, wIndex);
+	} else if (bus_state->port_remote_wakeup & (1 << port->hcd_portnum) &&
+		   !(raw_port_status & PORT_CONNECT)) {
+		bus_state->port_remote_wakeup &= ~(1 << port->hcd_portnum);
 	}
 
 	if (bus_state->port_c_suspend & (1 << wIndex))
-- 
2.22.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2019-07-02 11:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-02 11:12 [PATCH v2] xhci: clear port_remote_wakeup after resume failure Nicolas Saenz Julienne

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).