Avoid that it can take 200 ms too long to wait for requests to
finish. Note: blk_mq_freeze_queue() uses a wait queue to wait
for ongoing requests to finish.

Signed-off-by: Bart Van Assche <bart.vanass...@wdc.com>
Cc: Martin K. Petersen <martin.peter...@oracle.com>
Cc: Ming Lei <ming....@redhat.com>
Cc: Christoph Hellwig <h...@lst.de>
Cc: Hannes Reinecke <h...@suse.com>
Cc: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/scsi_lib.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ca84fd2d93ea..c5e66bb0c94d 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2939,10 +2939,20 @@ scsi_device_quiesce(struct scsi_device *sdev)
        if (err)
                return err;
 
-       scsi_run_queue(q);
-       while (atomic_read(&sdev->device_busy)) {
-               msleep_interruptible(200);
+       if (q->mq_ops) {
+               /*
+                * Ensure write order of the PREEMPT_ONLY queue flag and
+                * q_usage_counter. See also blk_queue_enter().
+                */
+               smp_wmb();
+               blk_mq_freeze_queue(q);
+               blk_mq_unfreeze_queue(q);
+       } else {
                scsi_run_queue(q);
+               while (atomic_read(&sdev->device_busy)) {
+                       msleep_interruptible(200);
+                       scsi_run_queue(q);
+               }
        }
        return 0;
 }
-- 
2.14.1

Reply via email to