Re: [PATCH] USB: Skip resume if pm_runtime_set_active() fails

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Feb 24, 2025 at 09:33:25AM +0800, Ma Ke wrote:
> A race condition occurs during system suspend if interrupted between
> usb_suspend() and the parent device’s PM suspend (e.g., a power
> domain).

I don't understand exactly what you mean.  Is this supposed to be a 
scenario where a USB device is suspended during a system sleep 
transition, but before the device's parent can be suspended, the 
sleep transition is aborted?

>  This triggers PM resume workflows (via usb_resume()), but if
> parent device is already runtime-suspended, pm_runtime_set_active()
> fails.

In other words, before the device can be resumed the parent goes into 
runtime suspend?  I don't understand how that could happen.  The PM core 
is careful to make sure that unwanted runtime PM changes don't occur 
during system sleep/resume transitions.

And if somehow this can happen, doesn't that indicate the real problem 
lies in the PM core?  After all, why shouldn't the same sort of race 
condition affect a device on any bus, not just USB devices?

>  Subsequent operations like pm_runtime_enable() and interface
> unbinding may leave the USB device in an inconsistent state or trigger
> unintended behavior.
> 
> Found by code review.
> 
> Cc: stable@xxxxxxxxxxxxxxx
> Fixes: 98d9a82e5f75 ("USB: cleanup the handling of the PM complete call")
> Signed-off-by: Ma Ke <make24@xxxxxxxxxxx>
> ---
>  drivers/usb/core/driver.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
> index 460d4dde5994..7478fcc11fd4 100644
> --- a/drivers/usb/core/driver.c
> +++ b/drivers/usb/core/driver.c
> @@ -1624,11 +1624,17 @@ int usb_resume(struct device *dev, pm_message_t msg)
>  	status = usb_resume_both(udev, msg);
>  	if (status == 0) {
>  		pm_runtime_disable(dev);
> -		pm_runtime_set_active(dev);
> +		status = pm_runtime_set_active(dev);
> +		if (status) {
> +			pm_runtime_enable(dev);

The patch description says that pm_runtime_enable() following an 
unsuccessful pm_runtime_set_active() may trigger unintended behavior.  
So why does the patch do it?

Alan Stern

> +			goto out;
> +		}
> +
>  		pm_runtime_enable(dev);
>  		unbind_marked_interfaces(udev);
>  	}
>  
> +out:
>  	/* Avoid PM error messages for devices disconnected while suspended
>  	 * as we'll display regular disconnect messages just a bit later.
>  	 */
> -- 
> 2.25.1
> 




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux