Commit cf48f79b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi into master

Pull SCSI fix from James Bottomley:
 "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"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: core: Run queue in case of I/O resource contention failure
parents 04300d66 3f0dcfbc
...@@ -547,6 +547,15 @@ static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd) ...@@ -547,6 +547,15 @@ static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
scsi_uninit_cmd(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 */ /* 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, static bool scsi_end_request(struct request *req, blk_status_t error,
unsigned int bytes) unsigned int bytes)
...@@ -591,11 +600,7 @@ static bool scsi_end_request(struct request *req, blk_status_t error, ...@@ -591,11 +600,7 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
__blk_mq_end_request(req, error); __blk_mq_end_request(req, error);
if (scsi_target(sdev)->single_lun || scsi_run_queue_async(sdev);
!list_empty(&sdev->host->starved_list))
kblockd_schedule_work(&sdev->requeue_work);
else
blk_mq_run_hw_queues(q, true);
percpu_ref_put(&q->q_usage_counter); percpu_ref_put(&q->q_usage_counter);
return false; return false;
...@@ -1702,6 +1707,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -1702,6 +1707,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
*/ */
if (req->rq_flags & RQF_DONTPREP) if (req->rq_flags & RQF_DONTPREP)
scsi_mq_uninit_cmd(cmd); scsi_mq_uninit_cmd(cmd);
scsi_run_queue_async(sdev);
break; break;
} }
return ret; return ret;
......
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