Re: [REGRESSION] 6.12.36+: usb: hub: post-resume delayed work triggers > uncorrected MCE / data fabric sync flood on Threadripper 7970X > (bisected to aec11e5f9c45)
From: Lovekesh Solanki
Date: Sun Aug 23 2026 - 11:18:17 EST
On Sun, Aug 23, 2026 at 12:36:55PM +0200, Thorsten Leemhuis wrote:
> that ticket apparently didn't help. And no other fix is in sight, or am
> I missing something?
>
> Mathias reverting the culprit in mainline a option to resolve this (I
> assume it is not, but I'm asking just to be sure)?
I don't think a revert is needed here, we're just trading one regression
for another.
Commit 8f5b7e2bec1c introduced the 200ms hold for all superspeed hubs,
but it's only useful for external ones. Root hubs are superspeed hubs
too so they go through the same code, but there's nothing useful for
the hold to do there:
A root hub has no upstream suspended hub whose wake propagation we need
to wait for and xhci already handles late USB3 link training itself.
Also hubs have a 0 second autosuspend delay (596d789a211d), so this hold
is the only thing stretching the awake window.
and anything opening or closing /dev/bus/usb nodes auto resumes and auto
suspends the whole host controller, adb's periodic enumeration does that
so on the reported affected systems every SS roothub cycle grows from
~30 to ~235ms (from the dynamic debug traces in
https://lore.kernel.org/all/qc0nhk9c6l0a08bkfeplrm3qjssgrjkvkp@xxxxxxxxx/)
which makes suspend move from close() call into delayed work and results
in the ~1Hz stress loop described upthread.
I think skipping the hold for hubs without a parent device, i.e. keep TB
dock behaviour everywhere it matters, should fix this.
Patch below could any of the reporters test it?
Thanks,
DrEggCake
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d92bf887739d..f642ea0c31dc 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1346,7 +1346,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
device_unlock(&hdev->dev);
}
- if (type == HUB_RESUME && hub_is_superspeed(hub->hdev)) {
+ if (type == HUB_RESUME && hub->hdev->parent &&
+ hub_is_superspeed(hub->hdev)) {
/* give usb3 downstream links training time after hub resume */
usb_autopm_get_interface_no_resume(
to_usb_interface(hub->intfdev));