Hi all,
This is the v3 patches to add ata port runtime pm support.
Applied on top of v3.2-rc2.
v1:
https://lkml.org/lkml/2011/11/2/23
v2:
https://lkml.org/lkml/2011/11/10/71
Acked-by: Tejun Heo <tj@kernel.org>
Kay Sievers reviewed sysfs change
Changes in v3:
- runtime resume scsi device before system suspend (Alan Stern)
- check runtime status in sd_shutdown
Thanks for any comment,
Lin Ming
Currently, the device tree of ata port and scsi host looks as below,
/sys/devices/pci0000:00/0000:00:1f.2 (ahci controller)
|-- ata1 (ata port)
|-- host0 (scsi host)
|-- target0:0:0 (scsi target)
|-- 0:0:0:0 (disk)
This patch makes ata port as parent device of scsi host, then it becomes
/sys/devices/pci0000:00/0000:00:1f.2 (ahci controller)
|-- ata1 (ata port)
|-- host0 (scsi host)
|-- target0:0:0 (scsi target)
|-- 0:0:0:0 (disk)
With this change, the ata port runtime PM is easier.
For example, the ata port runtime suspend will happen as,
disk suspend --> scsi target suspend --> scsi host suspend --> ata port
suspend.
Signed-off-by: Lin Ming <redacted>
---
drivers/ata/libata-scsi.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
From: Alan Stern <stern@rowland.harvard.edu>
scsi device runtime PM is using PMSG_SUSPEND. System PM may use other state
that may not be compatiable with PMSG_SUSPEND.
So we need to runtime resume the device before system suspend.
Signed-off-by: Lin Ming <redacted>
---
Alan,
Could you add your Signed-off-by?
Free free to change the commit logs.
drivers/scsi/scsi_pm.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
Change ata_host_request_pm to ata_port_request_pm which performs
port suspend/resume.
Add ata port type driver which implements port PM callbacks.
Signed-off-by: Lin Ming <redacted>
---
drivers/ata/libata-core.c | 144 ++++++++++++++++++++-------------------
drivers/ata/libata-transport.c | 1 +
drivers/ata/libata.h | 1 +
3 files changed, 76 insertions(+), 70 deletions(-)
Add ata port runtime suspend/resume/idle callbacks.
Set ->eh_noresume to skip the runtime PM calls on scsi host
in the error handler to avoid dead lock.
Signed-off-by: Lin Ming <redacted>
---
drivers/ata/libata-core.c | 10 ++++++++++
drivers/ata/libata-scsi.c | 1 +
drivers/ata/libata-transport.c | 4 ++++
3 files changed, 15 insertions(+), 0 deletions(-)
sd_shutdown is called during reboot/poweroff.
It may fail if parent device, for example, ata port, was runtime suspended.
Fix it by checking runtime status of sd.
Exit immediately if sd was runtime suspended already.
Signed-off-by: Lin Ming <redacted>
---
drivers/scsi/sd.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
With previous change, now the ata port runtime suspend will happen as:
disk suspend --> scsi target suspend --> scsi host suspend --> ata port
suspend
ata port(parent device) suspend need to schedule scsi EH which will resume
scsi host(child device). Then the child device resume will in turn make
parent device resume first. This is kind of recursive.
This patch adds a new flag Scsi_Host::eh_noresume.
ata port will set this flag to skip the runtime PM calls on scsi host.
Signed-off-by: Lin Ming <redacted>
---
drivers/scsi/scsi_error.c | 5 +++--
include/scsi/scsi_host.h | 3 +++
2 files changed, 6 insertions(+), 2 deletions(-)
From: Alan Stern <stern@rowland.harvard.edu> Date: 2011-11-23 17:02:42
On Wed, 23 Nov 2011, Lin Ming wrote:
From: Alan Stern <stern@rowland.harvard.edu>
scsi device runtime PM is using PMSG_SUSPEND. System PM may use other state
that may not be compatiable with PMSG_SUSPEND.
Actually SCSI runtime PM uses PMSG_AUTO_AUTOSUSPEND, which is the same
as PMSG_SUSPEND except that the PM_EVENT_AUTO bit is also set in the
pm_message.event field. Currently they _are_ compatible.
So we need to runtime resume the device before system suspend.
Signed-off-by: Lin Ming <redacted>
---
Alan,
Could you add your Signed-off-by?
Free free to change the commit logs.
I don't know; this is a little questionable.
The point of this patch is to handle drivers that do different things
for runtime suspend and system sleep. The only SCSI driver that
currently supports runtime suspend is sd, and it treats runtime suspend
the same as system sleep. (Earlier I said it doesn't spin down disks
for runtime suspend -- that was wrong, it does. It skips the spin-down
step only for PM_EVENT_FREEZE, which is part of the hibernation
procedure.)
Until other SCSI drivers support runtime suspend, this patch shouldn't
be needed. And spinning up runtime-suspended disks could add a lengthy
delay to the system sleep transition, so it's better not to do this if
at all possible.
Alan Stern
On Thu, 2011-11-24 at 01:02 +0800, Alan Stern wrote:
On Wed, 23 Nov 2011, Lin Ming wrote:
quoted
From: Alan Stern <stern@rowland.harvard.edu>
scsi device runtime PM is using PMSG_SUSPEND. System PM may use other state
that may not be compatiable with PMSG_SUSPEND.
Actually SCSI runtime PM uses PMSG_AUTO_AUTOSUSPEND, which is the same
as PMSG_SUSPEND except that the PM_EVENT_AUTO bit is also set in the
pm_message.event field. Currently they _are_ compatible.
quoted
So we need to runtime resume the device before system suspend.
Signed-off-by: Lin Ming <redacted>
---
Alan,
Could you add your Signed-off-by?
Free free to change the commit logs.
I don't know; this is a little questionable.
The point of this patch is to handle drivers that do different things
for runtime suspend and system sleep. The only SCSI driver that
currently supports runtime suspend is sd, and it treats runtime suspend
the same as system sleep. (Earlier I said it doesn't spin down disks
for runtime suspend -- that was wrong, it does. It skips the spin-down
step only for PM_EVENT_FREEZE, which is part of the hibernation
procedure.)
Until other SCSI drivers support runtime suspend, this patch shouldn't
be needed. And spinning up runtime-suspended disks could add a lengthy
delay to the system sleep transition, so it's better not to do this if
at all possible.
For sd driver, PMSG_SUSPEND and PMSG_HIBERNATE are compatible with
PMSG_AUTO_SUSPEND. PMSG_FREEZE is not compatible.
So we only need to runtime resume sd for PMSG_FREEZE case.
How about below?
From: Alan Stern <stern@rowland.harvard.edu> Date: 2011-11-24 16:36:23
On Thu, 24 Nov 2011, Lin Ming wrote:
quoted
The point of this patch is to handle drivers that do different things
for runtime suspend and system sleep. The only SCSI driver that
currently supports runtime suspend is sd, and it treats runtime suspend
the same as system sleep. (Earlier I said it doesn't spin down disks
for runtime suspend -- that was wrong, it does. It skips the spin-down
step only for PM_EVENT_FREEZE, which is part of the hibernation
procedure.)
Until other SCSI drivers support runtime suspend, this patch shouldn't
be needed. And spinning up runtime-suspended disks could add a lengthy
delay to the system sleep transition, so it's better not to do this if
at all possible.
For sd driver, PMSG_SUSPEND and PMSG_HIBERNATE are compatible with
PMSG_AUTO_SUSPEND. PMSG_FREEZE is not compatible.
I'm not sure what you mean. In the sd driver, PMSG_SUSPEND,
PMSG_HIBERNATE, and PMSG_AUTO_SUSPEND all do exactly the same thing.
PMSG_FREEZE does a little less -- it doesn't spin down the drive.
So we only need to runtime resume sd for PMSG_FREEZE case.
No, we don't. PMSG_FREEZE does not care whether the drive is spinning
or not. (That's why it skips the spin-down step.) Therefore it's
silly to restart a stopped drive just in order to do a PMSG_FREEZE.
Of course, this leaves the patch in pretty much the same state as what
Tejun objected to in
http://marc.info/?l=linux-ide&m=132136894329965&w=2
I think this email discussion has answered his objection: The only SCSI
top-level driver implementing runtime suspend is sd, and sd treats
runtime suspend the same as system sleep. It might be a good idea to
add a comment with this explanation along with the new code, however.
Alan Stern
Hello,
On Thu, Nov 24, 2011 at 11:36:20AM -0500, Alan Stern wrote:
I think this email discussion has answered his objection: The only SCSI
top-level driver implementing runtime suspend is sd, and sd treats
runtime suspend the same as system sleep. It might be a good idea to
add a comment with this explanation along with the new code, however.
Hmmm... I see. This shouldn't affect host controller states - we'll
be skipping only the drive PM transitions, right? As long as it's
well documented, I guess it's okay but at the same time I don't think
it's such a big deal to spin up drives when the system is entering
hibernation from runtime powersave. On most systems, they'll need to
be spun up for image dump pretty soon anyway.
Thanks.
--
tejun
From: Alan Stern <stern@rowland.harvard.edu> Date: 2011-11-24 22:54:40
On Thu, 24 Nov 2011, Tejun Heo wrote:
Hello,
On Thu, Nov 24, 2011 at 11:36:20AM -0500, Alan Stern wrote:
quoted
I think this email discussion has answered his objection: The only SCSI
top-level driver implementing runtime suspend is sd, and sd treats
runtime suspend the same as system sleep. It might be a good idea to
add a comment with this explanation along with the new code, however.
Hmmm... I see. This shouldn't affect host controller states - we'll
be skipping only the drive PM transitions, right?
Right.
As long as it's
well documented, I guess it's okay but at the same time I don't think
it's such a big deal to spin up drives when the system is entering
hibernation from runtime powersave. On most systems, they'll need to
be spun up for image dump pretty soon anyway.
Hmm, that's true. Or more precisely, they'll all be spun up for the
THAW stage of hibernation, prior to storing the memory image -- even
though the image is generally stored on only a single drive.
Okay, Ming, your most recent suggested patch can be used as is (though
adding a comment would be a good idea). Here's my suggestion for the
patch description:
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.
Alan Stern
Hello,
On Thu, Nov 24, 2011 at 2:54 PM, Alan Stern [off-list ref] 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;
}
I really don't think we need to optimize this further than this.
Thanks.
--
tejun
From: Alan Stern <stern@rowland.harvard.edu> Date: 2011-11-25 00:17:12
On Thu, 24 Nov 2011, Tejun Heo wrote:
Hello,
On Thu, Nov 24, 2011 at 2:54 PM, Alan Stern [off-list ref] wrote:
quoted
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
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
On Fri, 2011-11-25 at 08:17 +0800, Alan Stern wrote:
On Thu, 24 Nov 2011, Tejun Heo wrote:
quoted
Hello,
On Thu, Nov 24, 2011 at 2:54 PM, Alan Stern [off-list ref] wrote:
quoted
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 <redacted>
---
drivers/scsi/scsi_pm.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
@@ -49,8 +49,22 @@ static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg){interr=0;-if(scsi_is_sdev_device(dev))+if(scsi_is_sdev_device(dev)){+/*+*sdistheonlyhigh-levelSCSIdrivertoimplementruntime+*PM,andsdtreatsruntimesuspend,systemsuspend,and+*systemhibernateidentically(butnotsystemfreeze).+*/+if(pm_runtime_suspended(dev)){+if(msg.event==PM_EVENT_SUSPEND||+msg.event==PM_EVENT_HIBERNATE)+return0;/* already suspended */++/* wake up device so that FREEZE will succeed */+pm_runtime_resume(dev);+}err=scsi_dev_type_suspend(dev,msg);+}returnerr;}
---
Thanks,
Lin Ming
libata does not contain the SCSI device driver; it contains the host
driver.
quoted
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
From: Alan Stern <stern@rowland.harvard.edu> Date: 2011-11-25 15:20:00
On Fri, 25 Nov 2011, Lin Ming wrote:
quoted hunk
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 <redacted>
---
drivers/scsi/scsi_pm.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)
@@ -49,8 +49,22 @@ static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg){interr=0;-if(scsi_is_sdev_device(dev))+if(scsi_is_sdev_device(dev)){+/*+*sdistheonlyhigh-levelSCSIdrivertoimplementruntime+*PM,andsdtreatsruntimesuspend,systemsuspend,and+*systemhibernateidentically(butnotsystemfreeze).+*/+if(pm_runtime_suspended(dev)){+if(msg.event==PM_EVENT_SUSPEND||+msg.event==PM_EVENT_HIBERNATE)+return0;/* already suspended */++/* wake up device so that FREEZE will succeed */+pm_runtime_resume(dev);+}err=scsi_dev_type_suspend(dev,msg);+}returnerr;}
This looks good to me.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>