Re: [PATCH 1/2] PM: automatically retry failed autosuspends

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

 



On Thursday, November 03, 2011, Alan Stern wrote:
> Originally, the runtime PM core would send an idle notification
> whenever a suspend attempt failed.  The idle callback routine could
> then schedule a delayed suspend for some time later.
> 
> However this behavior was changed by commit
> f71648d73c1650b8b4aceb3856bebbde6daa3b86 (PM / Runtime: Remove idle
> notification after failing suspend).  No notifications were sent, and
> there was no clear mechanism to retry failed suspends.
> 
> This caused problems for the usbhid driver, because it fails
> autosuspend attempts as long as a key is being held down.  Therefore
> this patch (as1492) adds a mechanism for retrying failed
> autosuspends.  If the callback routine updates the last_busy field so
> that the next autosuspend expiration time is in the future, the
> autosuspend will automatically be rescheduled.
> 
> Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
> Tested-by: Henrik Rydberg <rydberg@xxxxxxxxxxx>
> CC: <stable@xxxxxxxxxx>

Applied to linux-pm/linux-next.

Thanks,
Rafael


> ---
> 
>  Documentation/power/runtime_pm.txt |   10 ++++++++++
>  drivers/base/power/runtime.c       |   18 ++++++++++++++++--
>  2 files changed, 26 insertions(+), 2 deletions(-)
> 
> Index: usb-3.1/Documentation/power/runtime_pm.txt
> ===================================================================
> --- usb-3.1.orig/Documentation/power/runtime_pm.txt
> +++ usb-3.1/Documentation/power/runtime_pm.txt
> @@ -789,6 +789,16 @@ will behave normally, not taking the aut
>  Similarly, if the power.use_autosuspend field isn't set then the autosuspend
>  helper functions will behave just like the non-autosuspend counterparts.
>  
> +Under some circumstances a driver or subsystem may want to prevent a device
> +from autosuspending immediately, even though the usage counter is zero and the
> +autosuspend delay time has expired.  If the ->runtime_suspend() callback
> +returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is
> +in the future (as it normally would be if the callback invoked
> +pm_runtime_mark_last_busy()), the PM core will automatically reschedule the
> +autosuspend.  The ->runtime_suspend() callback can't do this rescheduling
> +itself because no suspend requests of any kind are accepted while the device is
> +suspending (i.e., while the callback is running).
> +
>  The implementation is well suited for asynchronous use in interrupt contexts.
>  However such use inevitably involves races, because the PM core can't
>  synchronize ->runtime_suspend() callbacks with the arrival of I/O requests.
> Index: usb-3.1/drivers/base/power/runtime.c
> ===================================================================
> --- usb-3.1.orig/drivers/base/power/runtime.c
> +++ usb-3.1/drivers/base/power/runtime.c
> @@ -296,6 +296,9 @@ static int rpm_callback(int (*cb)(struct
>   * the callback was running then carry it out, otherwise send an idle
>   * notification for its parent (if the suspend succeeded and both
>   * ignore_children of parent->power and irq_safe of dev->power are not set).
> + * If ->runtime_suspend failed with -EAGAIN or -EBUSY, and if the RPM_AUTO
> + * flag is set and the next autosuspend-delay expiration time is in the
> + * future, schedule another autosuspend attempt.
>   *
>   * This function must be called under dev->power.lock with interrupts disabled.
>   */
> @@ -416,10 +419,21 @@ static int rpm_suspend(struct device *de
>  	if (retval) {
>  		__update_runtime_status(dev, RPM_ACTIVE);
>  		dev->power.deferred_resume = false;
> -		if (retval == -EAGAIN || retval == -EBUSY)
> +		if (retval == -EAGAIN || retval == -EBUSY) {
>  			dev->power.runtime_error = 0;
> -		else
> +
> +			/*
> +			 * If the callback routine failed an autosuspend, and
> +			 * if the last_busy time has been updated so that there
> +			 * is a new autosuspend expiration time, automatically
> +			 * reschedule another autosuspend.
> +			 */
> +			if ((rpmflags & RPM_AUTO) &&
> +			    pm_runtime_autosuspend_expiration(dev) != 0)
> +				goto repeat;
> +		} else {
>  			pm_runtime_cancel_pending(dev);
> +		}
>  		wake_up_all(&dev->power.wait_queue);
>  		goto out;
>  	}
> 
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux