Commit cf48f79b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -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 @@ out_put_budget:
		 */
		if (req->rq_flags & RQF_DONTPREP)
			scsi_mq_uninit_cmd(cmd);
		scsi_run_queue_async(sdev);
		break;
	}
	return ret;