From: Jianping Liu <frankljpliu@gmail.com>
To: gregkh@linuxfoundation.org, dakr@kernel.org,
shashank.mahadasyam@sony.com, johan@kernel.org,
hadess@hadess.net, frankjpliu@tencent.com, guanyulin@google.com,
gary@garyguo.net, rafael.j.wysocki@intel.com
Cc: linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org
Subject: [PATCH] usb: core: raise root-hub autosuspend delay to stop a busy-loop
Date: Wed, 28 Oct 2026 12:18:59 +0800 [thread overview]
Message-ID: <20261028041859.1061836-1-frankljpliu@gmail.com> (raw)
From: Jianping Liu <frankjpliu@tencent.com>
hub_probe() sets the hub autosuspend delay to 0. An idle hub is
therefore suspended at once, with no waiting time.
Suspending the root hub can fail. While a port reports over-current
or a connect change, xHCI refuses the bus suspend and returns -EBUSY.
usb_runtime_suspend() returns that error. The hub is resumed, and when
its status URB completes the same suspend runs again.
The PM core would normally leave a gap before that next attempt. It
starts the autosuspend timer only when the delay is still in the
future. A delay of 0 is already due, so no timer is started and there
is nothing to wait for. Suspend and resume repeat immediately, and one
CPU core stays at 100% until the port is no longer stuck.
If a root-hub runtime suspend fails while the delay is still 0, set
the delay to 1000 ms so the next attempt waits. If a later runtime
suspend succeeds and the delay is not 0, put it back to 0.
Signed-off-by: Jianping Liu <frankjpliu@tencent.com>
---
drivers/usb/core/driver.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index d3a61ebc6afb..30965d6ffd67 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -2008,6 +2008,20 @@ int usb_runtime_suspend(struct device *dev)
if (status == -EAGAIN || status == -EBUSY)
usb_mark_last_busy(udev);
+ /*
+ * Root hubs use 0ms delay, so a persistent -EBUSY retries with no
+ * wait and pins one CPU at 100%. Set autosuspend_delay to 1000ms
+ * on fail, then back to 0 ms on success.
+ */
+ if (!udev->parent) {
+ int delay = READ_ONCE(dev->power.autosuspend_delay);
+
+ if (unlikely(status != 0 && delay == 0))
+ pm_runtime_set_autosuspend_delay(dev, 1000);
+ if (unlikely(status == 0 && delay != 0))
+ pm_runtime_set_autosuspend_delay(dev, 0);
+ }
+
/*
* The PM core reacts badly unless the return code is 0,
* -EAGAIN, or -EBUSY, so always return -EBUSY on an error
--
2.43.7
next reply other threads:[~2026-10-28 4:19 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 4:18 Jianping Liu [this message]
2026-10-28 4:33 ` [PATCH] usb: core: raise root-hub autosuspend delay to stop a busy-loop sashiko-bot
2026-10-30 2:23 ` Alan Stern
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=20261028041859.1061836-1-frankljpliu@gmail.com \
--to=frankljpliu@gmail.com \
--cc=dakr@kernel.org \
--cc=frankjpliu@tencent.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=guanyulin@google.com \
--cc=hadess@hadess.net \
--cc=johan@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=rafael.j.wysocki@intel.com \
--cc=shashank.mahadasyam@sony.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.