Re: [RFC PATCH] usb: core: defer leaf-device resume off the S3 critical path
Oliver Neukum <[email protected]> Wed, 5 Aug 2026 15:28:58 +0200
| Newsgroups | org.kernel.vger.linux-usb,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 05.08.26 11:36, Hongyu Xie wrote: > Problem: > System resume (dpm_resume) invokes each device's resume callback > synchronously on the wake-up critical path. For a USB leaf device > this means port resume and, when reset_resume is needed, a port > reset that, for persistent devices, waits up to 2000 ms for the > device connection (CCS; on SuperSpeed this includes link training) > to be re-established (wait_for_connected()). Slow link training of > some U-disks and webcams after S3 power-on therefore stalls the > entire system wake-up: on an > arm64 test machine with four leaf devices (bluetooth, UVC camera, > two U-disks) dpm_resume took 2508 ms, about 2.1 s of it caused by a > single SanDisk U-disk whose link training stayed in Rx.Detect for > 2000 ms (worst case: -ENODEV fallback to disconnect + > re-enumeration). A device compatibility issue should not lengthen > the system-wide wake-up. > > Fix: > The patch addresses this on four levels: > > 1. Defer leaf-device recovery off the critical path. Leaf devices > (udev->parent && !udev->maxchild) that are port-suspended on > system resume have their real port resume moved to a per-device > work item queued from usb_resume_complete(), after all hubs have > finished resume. The work reuses the same udev (in-place reset, > devnum preserved); drivers without reset_resume get unbind+rebind. If you do this, you may have drivers which do not runtime PM face devices that are effectively runtime suspended. This will not work. > 2. Safe abandonment. If a new suspend or a disconnect arrives before > the work item runs, the reset is abandoned, not flushed: the > device is still port-suspended, which is exactly what the new > suspend needs, and the work item then only releases the runtime > reference it took. The abandon decision is serialized with the > work item by the device lock, so no cancel_work_sync() (which > would deadlock against the work item's device_lock()) is needed > on the suspend path. You cannot do this without checking whether remote_wakeup is correctly set. Furthermore you cannot just use the system work queue for this. You must not have any memory allocations with GFP_KERNEL on that queue. Regards Oliver