Small core patch to fix a corner case bug: we forgot to run the queues
to handle starvation in the error exit from the scsi_queue_rq routine,
which can lead to hangs on error conditions.

The patch is available here:

git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi-fixes

The short changelog is:

Ming Lei (1):
      scsi: core: Run queue in case of I/O resource contention failure

And the diffstat:

 drivers/scsi/scsi_lib.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

With full diff below.

James

---

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 0ba7a65e7c8d..06056e9ec333 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -547,6 +547,15 @@ static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
        scsi_uninit_cmd(cmd);
 }
 
+static void scsi_run_queue_async(struct scsi_device *sdev)
+{
+       if (scsi_target(sdev)->single_lun ||
+           !list_empty(&sdev->host->starved_list))
+               kblockd_schedule_work(&sdev->requeue_work);
+       else
+               blk_mq_run_hw_queues(sdev->request_queue, true);
+}
+
 /* Returns false when no more bytes to process, true if there are more */
 static bool scsi_end_request(struct request *req, blk_status_t error,
                unsigned int bytes)
@@ -591,11 +600,7 @@ static bool scsi_end_request(struct request *req, 
blk_status_t error,
 
        __blk_mq_end_request(req, error);
 
-       if (scsi_target(sdev)->single_lun ||
-           !list_empty(&sdev->host->starved_list))
-               kblockd_schedule_work(&sdev->requeue_work);
-       else
-               blk_mq_run_hw_queues(q, true);
+       scsi_run_queue_async(sdev);
 
        percpu_ref_put(&q->q_usage_counter);
        return false;
@@ -1702,6 +1707,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx 
*hctx,
                 */
                if (req->rq_flags & RQF_DONTPREP)
                        scsi_mq_uninit_cmd(cmd);
+               scsi_run_queue_async(sdev);
                break;
        }
        return ret;

Reply via email to