Skip to content

Commit 356fd26

Browse files
westerihtejun
authored andcommitted
scsi: Set request queue runtime PM status back to active on resume
We treat system suspend of SCSI devices pretty much the same as runtime suspend. If the device is already runtime suspended we leave it to that state during system suspend. On resume from system sleep we then resume the device and correct the runtime PM status back to "active". There is a problem with this because runtime PM status of the request queue in question is not changed (it will be in "suspended" state). When SCSI disk driver (sd.c) resumes the disk it sends START message to the device and because the request queue is still in "suspended" state blk_pm_peek_request() returns NULL preventing resume of the disk. The issue can be reproduced with following commands: # echo auto > /sys/block/sda/device/power/control # echo 15000 > /sys/block/sda/device/power/autosuspend_delay_ms [ 57.191706] sd 0:0:0:0: [sda] Synchronizing SCSI cache [ 57.380015] sd 0:0:0:0: [sda] Stopping disk Now suspend the machine: # rtcwake -s10 -mmem This ends up in soft lockup because resume is not proceeding accordingly and userspace is never restarted. Also there is nothing printed to the console. Fix this by forcing request queue status to "active" before the disk is resumed. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent d07ab6d commit 356fd26

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

drivers/scsi/scsi_pm.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ static int scsi_bus_resume_common(struct device *dev,
139139
else
140140
fn = NULL;
141141

142+
/*
143+
* Forcibly set runtime PM status of request queue to "active" to
144+
* make sure we can again get requests from the queue (see also
145+
* blk_pm_peek_request()).
146+
*
147+
* The resume hook will correct runtime PM status of the disk.
148+
*/
149+
if (scsi_is_sdev_device(dev) && pm_runtime_suspended(dev))
150+
blk_set_runtime_active(to_scsi_device(dev)->request_queue);
151+
142152
if (fn) {
143153
async_schedule_domain(fn, dev, &scsi_sd_pm_domain);
144154

0 commit comments

Comments
 (0)