diff options
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index c7fccbb8f554..fa6e0c3b3aa6 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -697,6 +697,12 @@ static bool scsi_end_request(struct request *req, blk_status_t error, | |||
697 | */ | 697 | */ |
698 | scsi_mq_uninit_cmd(cmd); | 698 | scsi_mq_uninit_cmd(cmd); |
699 | 699 | ||
700 | /* | ||
701 | * queue is still alive, so grab the ref for preventing it | ||
702 | * from being cleaned up during running queue. | ||
703 | */ | ||
704 | percpu_ref_get(&q->q_usage_counter); | ||
705 | |||
700 | __blk_mq_end_request(req, error); | 706 | __blk_mq_end_request(req, error); |
701 | 707 | ||
702 | if (scsi_target(sdev)->single_lun || | 708 | if (scsi_target(sdev)->single_lun || |
@@ -704,6 +710,8 @@ static bool scsi_end_request(struct request *req, blk_status_t error, | |||
704 | kblockd_schedule_work(&sdev->requeue_work); | 710 | kblockd_schedule_work(&sdev->requeue_work); |
705 | else | 711 | else |
706 | blk_mq_run_hw_queues(q, true); | 712 | blk_mq_run_hw_queues(q, true); |
713 | |||
714 | percpu_ref_put(&q->q_usage_counter); | ||
707 | } else { | 715 | } else { |
708 | unsigned long flags; | 716 | unsigned long flags; |
709 | 717 | ||