Commit 8f38f8e0 authored by Alan Stern's avatar Alan Stern Committed by Martin K. Petersen

scsi: block: pm: Simplify resume handling

Commit 05d18ae1 ("scsi: pm: Balance pm_only counter of request queue
during system resume") fixed a problem in the block layer's runtime-PM
code: blk_set_runtime_active() failed to call blk_clear_pm_only().
However, the commit's implementation was awkward; it forced the SCSI
system-resume handler to choose whether to call blk_post_runtime_resume()
or blk_set_runtime_active(), depending on whether or not the SCSI device
had previously been runtime suspended.

This patch simplifies the situation considerably by adding the missing
function call directly into blk_set_runtime_active() (under the condition
that the queue is not already in the RPM_ACTIVE state).  This allows the
SCSI routine to revert back to its original form.  Furthermore, making this
change reveals that blk_post_runtime_resume() (in its success pathway) does
exactly the same thing as blk_set_runtime_active().  The duplicate code is
easily removed by making one routine call the other.

No functional changes are intended.

Link: https://lore.kernel.org/r/20200706151436.GA702867@rowland.harvard.edu
CC: Can Guo <cang@codeaurora.org>
CC: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent df4ec2fa
...@@ -164,9 +164,8 @@ EXPORT_SYMBOL(blk_pre_runtime_resume); ...@@ -164,9 +164,8 @@ EXPORT_SYMBOL(blk_pre_runtime_resume);
* *
* Description: * Description:
* Update the queue's runtime status according to the return value of the * Update the queue's runtime status according to the return value of the
* device's runtime_resume function. If it is successfully resumed, process * device's runtime_resume function. If the resume was successful, call
* the requests that are queued into the device's queue when it is resuming * blk_set_runtime_active() to do the real work of restarting the queue.
* and then mark last busy and initiate autosuspend for it.
* *
* This function should be called near the end of the device's * This function should be called near the end of the device's
* runtime_resume callback. * runtime_resume callback.
...@@ -175,19 +174,13 @@ void blk_post_runtime_resume(struct request_queue *q, int err) ...@@ -175,19 +174,13 @@ void blk_post_runtime_resume(struct request_queue *q, int err)
{ {
if (!q->dev) if (!q->dev)
return; return;
spin_lock_irq(&q->queue_lock);
if (!err) { if (!err) {
q->rpm_status = RPM_ACTIVE; blk_set_runtime_active(q);
pm_runtime_mark_last_busy(q->dev);
pm_request_autosuspend(q->dev);
} else { } else {
spin_lock_irq(&q->queue_lock);
q->rpm_status = RPM_SUSPENDED; q->rpm_status = RPM_SUSPENDED;
spin_unlock_irq(&q->queue_lock);
} }
spin_unlock_irq(&q->queue_lock);
if (!err)
blk_clear_pm_only(q);
} }
EXPORT_SYMBOL(blk_post_runtime_resume); EXPORT_SYMBOL(blk_post_runtime_resume);
...@@ -204,15 +197,25 @@ EXPORT_SYMBOL(blk_post_runtime_resume); ...@@ -204,15 +197,25 @@ EXPORT_SYMBOL(blk_post_runtime_resume);
* This function can be used in driver's resume hook to correct queue * This function can be used in driver's resume hook to correct queue
* runtime PM status and re-enable peeking requests from the queue. It * runtime PM status and re-enable peeking requests from the queue. It
* should be called before first request is added to the queue. * should be called before first request is added to the queue.
*
* This function is also called by blk_post_runtime_resume() for successful
* runtime resumes. It does everything necessary to restart the queue.
*/ */
void blk_set_runtime_active(struct request_queue *q) void blk_set_runtime_active(struct request_queue *q)
{ {
if (q->dev) { int old_status;
spin_lock_irq(&q->queue_lock);
q->rpm_status = RPM_ACTIVE; if (!q->dev)
pm_runtime_mark_last_busy(q->dev); return;
pm_request_autosuspend(q->dev);
spin_unlock_irq(&q->queue_lock); spin_lock_irq(&q->queue_lock);
} old_status = q->rpm_status;
q->rpm_status = RPM_ACTIVE;
pm_runtime_mark_last_busy(q->dev);
pm_request_autosuspend(q->dev);
spin_unlock_irq(&q->queue_lock);
if (old_status != RPM_ACTIVE)
blk_clear_pm_only(q);
} }
EXPORT_SYMBOL(blk_set_runtime_active); EXPORT_SYMBOL(blk_set_runtime_active);
...@@ -80,10 +80,6 @@ static int scsi_dev_type_resume(struct device *dev, ...@@ -80,10 +80,6 @@ static int scsi_dev_type_resume(struct device *dev,
dev_dbg(dev, "scsi resume: %d\n", err); dev_dbg(dev, "scsi resume: %d\n", err);
if (err == 0) { if (err == 0) {
bool was_runtime_suspended;
was_runtime_suspended = pm_runtime_suspended(dev);
pm_runtime_disable(dev); pm_runtime_disable(dev);
err = pm_runtime_set_active(dev); err = pm_runtime_set_active(dev);
pm_runtime_enable(dev); pm_runtime_enable(dev);
...@@ -97,10 +93,8 @@ static int scsi_dev_type_resume(struct device *dev, ...@@ -97,10 +93,8 @@ static int scsi_dev_type_resume(struct device *dev,
*/ */
if (!err && scsi_is_sdev_device(dev)) { if (!err && scsi_is_sdev_device(dev)) {
struct scsi_device *sdev = to_scsi_device(dev); struct scsi_device *sdev = to_scsi_device(dev);
if (was_runtime_suspended)
blk_post_runtime_resume(sdev->request_queue, 0); blk_set_runtime_active(sdev->request_queue);
else
blk_set_runtime_active(sdev->request_queue);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment