scsi: scsi_transport_spi: Set RQF_PM for domain validation commands
authorBart Van Assche <bvanassche@acm.org>
Wed, 9 Dec 2020 05:29:48 +0000 (21:29 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 9 Dec 2020 16:41:42 +0000 (11:41 -0500)
Disable runtime power management during domain validation. Since a later
patch removes RQF_PREEMPT, set RQF_PM for domain validation commands such
that these are executed in the quiesced SCSI device state.

Link: https://lore.kernel.org/r/20201209052951.16136-6-bvanassche@acm.org
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Woody Suwalski <terraluna977@gmail.com>
Cc: Can Guo <cang@codeaurora.org>
Cc: Stanley Chu <stanley.chu@mediatek.com>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Stan Johnson <userm57@yahoo.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jens Axboe <axboe@kernel.dk>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_transport_spi.c

index f3d5b1bbd5aa7eff36c5d91cd9d2df6e41a77f8d..c37dd15d16d24f20b6065e6d7141da6c955fd58c 100644 (file)
@@ -117,12 +117,16 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd,
                sshdr = &sshdr_tmp;
 
        for(i = 0; i < DV_RETRIES; i++) {
+               /*
+                * The purpose of the RQF_PM flag below is to bypass the
+                * SDEV_QUIESCE state.
+                */
                result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense,
                                      sshdr, DV_TIMEOUT, /* retries */ 1,
                                      REQ_FAILFAST_DEV |
                                      REQ_FAILFAST_TRANSPORT |
                                      REQ_FAILFAST_DRIVER,
-                                     0, NULL);
+                                     RQF_PM, NULL);
                if (driver_byte(result) != DRIVER_SENSE ||
                    sshdr->sense_key != UNIT_ATTENTION)
                        break;
@@ -1005,23 +1009,26 @@ spi_dv_device(struct scsi_device *sdev)
         */
        lock_system_sleep();
 
+       if (scsi_autopm_get_device(sdev))
+               goto unlock_system_sleep;
+
        if (unlikely(spi_dv_in_progress(starget)))
-               goto unlock;
+               goto put_autopm;
 
        if (unlikely(scsi_device_get(sdev)))
-               goto unlock;
+               goto put_autopm;
 
        spi_dv_in_progress(starget) = 1;
 
        buffer = kzalloc(len, GFP_KERNEL);
 
        if (unlikely(!buffer))
-               goto out_put;
+               goto put_sdev;
 
        /* We need to verify that the actual device will quiesce; the
         * later target quiesce is just a nice to have */
        if (unlikely(scsi_device_quiesce(sdev)))
-               goto out_free;
+               goto free_buffer;
 
        scsi_target_quiesce(starget);
 
@@ -1041,12 +1048,16 @@ spi_dv_device(struct scsi_device *sdev)
 
        spi_initial_dv(starget) = 1;
 
- out_free:
+free_buffer:
        kfree(buffer);
- out_put:
+
+put_sdev:
        spi_dv_in_progress(starget) = 0;
        scsi_device_put(sdev);
-unlock:
+put_autopm:
+       scsi_autopm_put_device(sdev);
+
+unlock_system_sleep:
        unlock_system_sleep();
 }
 EXPORT_SYMBOL(spi_dv_device);