diff options
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
| -rw-r--r-- | drivers/scsi/scsi_lib.c | 36 | 
1 files changed, 17 insertions, 19 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0ba7a65e7c8d..c866a4f33871 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; @@ -1589,31 +1594,23 @@ static blk_status_t scsi_mq_prep_fn(struct request *req)  static void scsi_mq_done(struct scsi_cmnd *cmd)  { +	if (unlikely(blk_should_fake_timeout(cmd->request->q))) +		return;  	if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state)))  		return;  	trace_scsi_dispatch_cmd_done(cmd); - -	/* -	 * If the block layer didn't complete the request due to a timeout -	 * injection, scsi must clear its internal completed state so that the -	 * timeout handler will see it needs to escalate its own error -	 * recovery. -	 */ -	if (unlikely(!blk_mq_complete_request(cmd->request))) -		clear_bit(SCMD_STATE_COMPLETE, &cmd->state); +	blk_mq_complete_request(cmd->request);  } -static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx) +static void scsi_mq_put_budget(struct request_queue *q)  { -	struct request_queue *q = hctx->queue;  	struct scsi_device *sdev = q->queuedata;  	atomic_dec(&sdev->device_busy);  } -static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) +static bool scsi_mq_get_budget(struct request_queue *q)  { -	struct request_queue *q = hctx->queue;  	struct scsi_device *sdev = q->queuedata;  	return scsi_dev_queue_ready(q, sdev); @@ -1680,7 +1677,7 @@ out_dec_target_busy:  	if (scsi_target(sdev)->can_queue > 0)  		atomic_dec(&scsi_target(sdev)->target_busy);  out_put_budget: -	scsi_mq_put_budget(hctx); +	scsi_mq_put_budget(q);  	switch (ret) {  	case BLK_STS_OK:  		break; @@ -1702,6 +1699,7 @@ out_put_budget:  		 */  		if (req->rq_flags & RQF_DONTPREP)  			scsi_mq_uninit_cmd(cmd); +		scsi_run_queue_async(sdev);  		break;  	}  	return ret;  | 
