Patchwork [v3,3/6,SCSI] runtime resume device before system suspend

login
register
mail settings
Submitter Lin Ming
Date Nov. 25, 2011, 1:50 p.m.
Message ID <1322229039.4246.8.camel@hp6530s>
Download mbox | patch
Permalink /patch/127700/
State Not Applicable
Delegated to: David Miller
Headers show

Comments

Lin Ming - Nov. 25, 2011, 1:50 p.m.
On Fri, 2011-11-25 at 08:17 +0800, Alan Stern wrote:
> On Thu, 24 Nov 2011, Tejun Heo wrote:
> 
> > Hello,
> > 
> > On Thu, Nov 24, 2011 at 2:54 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > > Therefore, when entering the SUSPEND or HIBERNATE stages of system
> > > sleep, we can skip the callback to the driver if the device is already
> > > in runtime suspend. �When entering the FREEZE stage, however, we should
> > > first issue a runtime resume. �The overhead of doing this is
> > > negligible, because a suspended drive would be spun up during the THAW
> > > stage of hibernation anyway.
> > 
> > My brain is half fried at the moment so maybe you're saying the same
> > thing, but I hope this is something simple. Like...
> > 
> >     /* for libata runtime suspend is equivalent to suspend */
> >     if (runtime suspended && target == SUSPEND) {
> >         yeah! skip drive pm ops;
> >     } else {
> >         end runtime pm;
> >         ask EH to enter target PM state;
> >     }
> 
> Almost.  More like this:
> 
> 	/*
> 	 * sd is the only high-level SCSI driver to implement runtime 
> 	 * PM, and sd treats runtime suspend, system suspend, and 
> 	 * system hibernate identically (but not system freeze).
> 	 */
> 	if (runtime-suspended) {
> 		if (target == SUSPEND || target == HIBERNATE)
> 			return 0;	/* already suspended */
> 		/* wake up device so that FREEZE will succeed */
> 		pm_runtime_resume();
> 	}
> 	tell device driver to enter target PM state

Below is the updated patch with your suggested patch description and
comments.

Looks OK?

Subject: [PATCH] [SCSI] check runtime PM status in system PM

The only high-level SCSI driver that currently implements runtime PM is
sd, and sd treats runtime suspend exactly the same as the SUSPEND and
HIBERNATE stages of system sleep, but not the same as the FREEZE stage.

Therefore, when entering the SUSPEND or HIBERNATE stages of system
sleep, we can skip the callback to the driver if the device is already
in runtime suspend.  When entering the FREEZE stage, however, we should
first issue a runtime resume.  The overhead of doing this is
negligible, because a suspended drive would be spun up during the THAW
stage of hibernation anyway.

Signed-off-by: Lin Ming <ming.m.lin@intel.com>
---
 drivers/scsi/scsi_pm.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

Thanks,
Lin Ming

> 
> libata does not contain the SCSI device driver; it contains the host
> driver.
> 
> > I really don't think we need to optimize this further than this.
> 
> The above has two lines (plus comments) of optimization.  Okay?
> 
> Alan Stern
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Stern - Nov. 25, 2011, 3:19 p.m.
On Fri, 25 Nov 2011, Lin Ming wrote:

> Below is the updated patch with your suggested patch description and
> comments.
> 
> Looks OK?
> 
> Subject: [PATCH] [SCSI] check runtime PM status in system PM
> 
> The only high-level SCSI driver that currently implements runtime PM is
> sd, and sd treats runtime suspend exactly the same as the SUSPEND and
> HIBERNATE stages of system sleep, but not the same as the FREEZE stage.
> 
> Therefore, when entering the SUSPEND or HIBERNATE stages of system
> sleep, we can skip the callback to the driver if the device is already
> in runtime suspend.  When entering the FREEZE stage, however, we should
> first issue a runtime resume.  The overhead of doing this is
> negligible, because a suspended drive would be spun up during the THAW
> stage of hibernation anyway.
> 
> Signed-off-by: Lin Ming <ming.m.lin@intel.com>
> ---
>  drivers/scsi/scsi_pm.c |   16 +++++++++++++++-
>  1 files changed, 15 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
> index d329f8b..a633076 100644
> --- a/drivers/scsi/scsi_pm.c
> +++ b/drivers/scsi/scsi_pm.c
> @@ -49,8 +49,22 @@ static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
>  {
>  	int err = 0;
>  
> -	if (scsi_is_sdev_device(dev))
> +	if (scsi_is_sdev_device(dev)) {
> +		/*
> +		 * sd is the only high-level SCSI driver to implement runtime
> +		 * PM, and sd treats runtime suspend, system suspend, and
> +		 * system hibernate identically (but not system freeze).
> +		 */
> +		if (pm_runtime_suspended(dev)) {
> +			if (msg.event == PM_EVENT_SUSPEND ||
> +			    msg.event == PM_EVENT_HIBERNATE)
> +				return 0;	/* already suspended */
> +
> +			/* wake up device so that FREEZE will succeed */
> +			pm_runtime_resume(dev);
> +		}
>  		err = scsi_dev_type_suspend(dev, msg);
> +	}
>  	return err;
>  }

This looks good to me.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>

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

Patch

diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index d329f8b..a633076 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -49,8 +49,22 @@  static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
 {
 	int err = 0;
 
-	if (scsi_is_sdev_device(dev))
+	if (scsi_is_sdev_device(dev)) {
+		/*
+		 * sd is the only high-level SCSI driver to implement runtime
+		 * PM, and sd treats runtime suspend, system suspend, and
+		 * system hibernate identically (but not system freeze).
+		 */
+		if (pm_runtime_suspended(dev)) {
+			if (msg.event == PM_EVENT_SUSPEND ||
+			    msg.event == PM_EVENT_HIBERNATE)
+				return 0;	/* already suspended */
+
+			/* wake up device so that FREEZE will succeed */
+			pm_runtime_resume(dev);
+		}
 		err = scsi_dev_type_suspend(dev, msg);
+	}
 	return err;
 }

---