From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: Eric Blau <eblau@eblau.com>, Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb@vger.kernel.org
Subject: [regression] USB power management failure to suspend / high CPU usage
Date: Thu, 14 Feb 2019 16:57:59 +0200 [thread overview]
Message-ID: <d0ae941c-5de2-bafe-9d48-f1c0c300b888@linux.intel.com> (raw)
On 12.2.2019 20.55, Eric Blau wrote:
> On Tue, Feb 12, 2019 at 1:06 PM Alan Stern <stern@rowland.harvard.edu> wrote:
>>
>> On Tue, 12 Feb 2019, Mathias Nyman wrote:
>>
>>>
>>> This logs shows a USB3 Apple card reader successfully suspending to U3 state
>>> once, but fails to resume back to U0. It is logically disconnected as a result of
>>> failing to resume, and is left stuck in a polling link state.
>>>
>>> This is the only USB3 device connected. The polling link state does not yet show the device
>>> as connected or enabled, so hub attempts to autosuspend.
>>> There is however a final check before autosuspending the hub which prevents suspend
>>> due to the port in polling state. This autosuspend attempt continues in a loop.
>>
>> I don't know what the right answer is here. But we shouldn't allow
>> faulty peripherals to prevent the system from going into suspend.
>>
>> Should we give up after some fixed number of warm resets, say 5?
>
I don't think the current code gets as far as warm resetting the port.
It seems to be stuck in the suspend attempt loop.
> Thanks for looking into this, Mathias. Now that you point this out, on
> older kernels where suspend and resume works, I noticed the following
> log messages emitted when resuming from suspend:
>
> Feb 06 18:58:05 eric-macbookpro kernel: usb usb2-port3: Cannot enable.
> Maybe the USB cable is bad?
Attached a testpatch that should react to ports stuck in polling state,
and warm reset them.
It doesn't limit the numbers of reset tries, or allow system suspend with ports
stuck in polling state, but I'd like to know how the MacBook reacts to it
Can you test it with debugging enabled?
Thanks
Mathias
From 6b3b9f3d41b8ac9cf993bf4b88a20e30c99e3b7f Mon Sep 17 00:00:00 2001
From: Mathias Nyman <mathias.nyman@linux.intel.com>
Date: Thu, 14 Feb 2019 15:40:12 +0200
Subject: [PATCH] usb: warm reset USB3 ports stuck in polling
warm reset USB3 ports stuck in polling after 360ms.
In the polling state USB3 ports are link training, which should
not take longer than 360ms according to USB3 specification
tPollingLFPSTimeout value.
The card reader connected to xhci in MacBookPro is found stuck
in this state after resuming from suspend.
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/core/hub.c | 36 +++++++++++++++++++++++++++++++++---
1 file changed, 33 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 8d4631c..448884d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1151,9 +1151,10 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
*/
if (hub_is_superspeed(hdev) &&
((portstatus & USB_PORT_STAT_LINK_STATE) ==
- USB_SS_PORT_LS_POLLING))
+ USB_SS_PORT_LS_POLLING)) {
need_debounce_delay = true;
-
+ set_bit(port1, hub->event_bits);
+ }
/* Clear status-change flags; we'll debounce later */
if (portchange & USB_PORT_STAT_C_CONNECTION) {
need_debounce_delay = true;
@@ -2697,6 +2698,9 @@ static unsigned hub_is_wusb(struct usb_hub *hub)
#define HUB_LONG_RESET_TIME 200
#define HUB_RESET_TIMEOUT 800
+#define HUB_LFPS_TIME 24
+#define HUB_LFPS_TIMEOUT 360
+
/*
* "New scheme" enumeration causes an extra state transition to be
* exposed to an xhci host and causes USB3 devices to receive control
@@ -2737,6 +2741,31 @@ static bool hub_port_warm_reset_required(struct usb_hub *hub, int port1,
|| link_state == USB_SS_PORT_LS_COMP_MOD;
}
+static bool hub_port_stuck_in_polling(struct usb_hub *hub, int port1,
+ u16 portstatus)
+{
+ u16 link_state;
+ u16 portchange;
+ int lfps_delay = 0;
+
+ if (!hub_is_superspeed(hub->hdev))
+ return false;
+
+ link_state = portstatus & USB_PORT_STAT_LINK_STATE;
+
+ while (link_state == USB_SS_PORT_LS_POLLING) {
+ msleep(HUB_LFPS_TIME);
+
+ hub_port_status(hub, port1, &portstatus, &portchange);
+ link_state = portstatus & USB_PORT_STAT_LINK_STATE;
+
+ lfps_delay += HUB_LFPS_TIME;
+ if (lfps_delay > HUB_LFPS_TIMEOUT)
+ return true;
+ }
+ return false;
+}
+
static int hub_port_wait_reset(struct usb_hub *hub, int port1,
struct usb_device *udev, unsigned int delay, bool warm)
{
@@ -5329,7 +5358,8 @@ static void port_event(struct usb_hub *hub, int port1)
* Warm reset a USB3 protocol port if it's in
* SS.Inactive state.
*/
- if (hub_port_warm_reset_required(hub, port1, portstatus)) {
+ if (hub_port_warm_reset_required(hub, port1, portstatus) ||
+ hub_port_stuck_in_polling(hub, port1, portstatus)) {
dev_dbg(&port_dev->dev, "do warm reset\n");
if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION)
|| udev->state == USB_STATE_NOTATTACHED) {
--
2.7.4
next reply other threads:[~2019-02-14 14:57 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-14 14:57 Mathias Nyman [this message]
-- strict thread matches above, loose matches on Subject: below --
2019-02-20 17:28 [regression] USB power management failure to suspend / high CPU usage Mathias Nyman
2019-02-22 1:05 Eric Blau
2019-02-25 22:11 Ivan Mironov
2019-03-04 15:15 Mathias Nyman
2019-03-04 15:53 Eric Blau
2019-03-21 13:32 Eric Blau
2019-03-21 14:54 Mathias Nyman
2019-03-21 15:40 Eric Blau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d0ae941c-5de2-bafe-9d48-f1c0c300b888@linux.intel.com \
--to=mathias.nyman@linux.intel.com \
--cc=eblau@eblau.com \
--cc=linux-usb@vger.kernel.org \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).