Skip to content

Commit e6044f7

Browse files
bvanasschemartinkpetersen
authored andcommitted
scsi: core: Only process PM requests if rpm_status != RPM_ACTIVE
Instead of submitting all SCSI commands submitted with scsi_execute() to a SCSI device if rpm_status != RPM_ACTIVE, only submit RQF_PM (power management requests) if rpm_status != RPM_ACTIVE. This patch makes the SCSI core handle the runtime power management status (rpm_status) as it should be handled. Link: https://lore.kernel.org/r/[email protected] Cc: Can Guo <[email protected]> Cc: Stanley Chu <[email protected]> Cc: Alan Stern <[email protected]> Cc: Ming Lei <[email protected]> Cc: Rafael J. Wysocki <[email protected]> Cc: Martin Kepplinger <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: Jens Axboe <[email protected]> Reviewed-by: Can Guo <[email protected]> Signed-off-by: Bart Van Assche <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent cfefd9f commit e6044f7

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

drivers/scsi/scsi_lib.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
249249

250250
req = blk_get_request(sdev->request_queue,
251251
data_direction == DMA_TO_DEVICE ?
252-
REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, BLK_MQ_REQ_PREEMPT);
252+
REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
253+
rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0);
253254
if (IS_ERR(req))
254255
return ret;
255256
rq = scsi_req(req);
@@ -1206,6 +1207,8 @@ static blk_status_t
12061207
scsi_device_state_check(struct scsi_device *sdev, struct request *req)
12071208
{
12081209
switch (sdev->sdev_state) {
1210+
case SDEV_CREATED:
1211+
return BLK_STS_OK;
12091212
case SDEV_OFFLINE:
12101213
case SDEV_TRANSPORT_OFFLINE:
12111214
/*
@@ -1232,18 +1235,18 @@ scsi_device_state_check(struct scsi_device *sdev, struct request *req)
12321235
return BLK_STS_RESOURCE;
12331236
case SDEV_QUIESCE:
12341237
/*
1235-
* If the devices is blocked we defer normal commands.
1238+
* If the device is blocked we only accept power management
1239+
* commands.
12361240
*/
1237-
if (req && !(req->rq_flags & RQF_PREEMPT))
1241+
if (req && WARN_ON_ONCE(!(req->rq_flags & RQF_PM)))
12381242
return BLK_STS_RESOURCE;
12391243
return BLK_STS_OK;
12401244
default:
12411245
/*
12421246
* For any other not fully online state we only allow
1243-
* special commands. In particular any user initiated
1244-
* command is not allowed.
1247+
* power management commands.
12451248
*/
1246-
if (req && !(req->rq_flags & RQF_PREEMPT))
1249+
if (req && !(req->rq_flags & RQF_PM))
12471250
return BLK_STS_IOERR;
12481251
return BLK_STS_OK;
12491252
}
@@ -2517,15 +2520,13 @@ void sdev_evt_send_simple(struct scsi_device *sdev,
25172520
EXPORT_SYMBOL_GPL(sdev_evt_send_simple);
25182521

25192522
/**
2520-
* scsi_device_quiesce - Block user issued commands.
2523+
* scsi_device_quiesce - Block all commands except power management.
25212524
* @sdev: scsi device to quiesce.
25222525
*
25232526
* This works by trying to transition to the SDEV_QUIESCE state
25242527
* (which must be a legal transition). When the device is in this
2525-
* state, only special requests will be accepted, all others will
2526-
* be deferred. Since special requests may also be requeued requests,
2527-
* a successful return doesn't guarantee the device will be
2528-
* totally quiescent.
2528+
* state, only power management requests will be accepted, all others will
2529+
* be deferred.
25292530
*
25302531
* Must be called with user context, may sleep.
25312532
*
@@ -2587,12 +2588,12 @@ void scsi_device_resume(struct scsi_device *sdev)
25872588
* device deleted during suspend)
25882589
*/
25892590
mutex_lock(&sdev->state_mutex);
2591+
if (sdev->sdev_state == SDEV_QUIESCE)
2592+
scsi_device_set_state(sdev, SDEV_RUNNING);
25902593
if (sdev->quiesced_by) {
25912594
sdev->quiesced_by = NULL;
25922595
blk_clear_pm_only(sdev->request_queue);
25932596
}
2594-
if (sdev->sdev_state == SDEV_QUIESCE)
2595-
scsi_device_set_state(sdev, SDEV_RUNNING);
25962597
mutex_unlock(&sdev->state_mutex);
25972598
}
25982599
EXPORT_SYMBOL(scsi_device_resume);

0 commit comments

Comments
 (0)