aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
authorMing Lei <ming.lei@redhat.com>2017-11-03 21:55:34 -0400
committerJens Axboe <axboe@kernel.dk>2017-11-04 10:19:25 -0400
commit826a70a08b1210bbfdbda812ab43eb986e25b5c2 (patch)
tree34ffcdb1ac15fef880c93219cc4f5df4fe1785c8 /drivers/scsi/scsi_lib.c
parente4f36b249b4d4e7599f1cf0c8fb50f196e52677e (diff)
SCSI: don't get target/host busy_count in scsi_mq_get_budget()
It is very expensive to atomic_inc/atomic_dec the host wide counter of host->busy_count, and it should have been avoided via blk-mq's mechanism of getting driver tag, which uses the more efficient way of sbitmap queue. Also we don't check atomic_read(&sdev->device_busy) in scsi_mq_get_budget() and don't run queue if the counter becomes zero, so IO hang may be caused if all requests are completed just before the current SCSI device is added to shost->starved_list. Fixes: 0df21c86bdbf(scsi: implement .get_budget and .put_budget for blk-mq) Reported-by: Bart Van Assche <bart.vanassche@wdc.com> Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 6f10afaca25b..22a7e4c47207 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1950,11 +1950,7 @@ static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx)
1950{ 1950{
1951 struct request_queue *q = hctx->queue; 1951 struct request_queue *q = hctx->queue;
1952 struct scsi_device *sdev = q->queuedata; 1952 struct scsi_device *sdev = q->queuedata;
1953 struct Scsi_Host *shost = sdev->host;
1954 1953
1955 atomic_dec(&shost->host_busy);
1956 if (scsi_target(sdev)->can_queue > 0)
1957 atomic_dec(&scsi_target(sdev)->target_busy);
1958 atomic_dec(&sdev->device_busy); 1954 atomic_dec(&sdev->device_busy);
1959 put_device(&sdev->sdev_gendev); 1955 put_device(&sdev->sdev_gendev);
1960} 1956}
@@ -1963,7 +1959,6 @@ static blk_status_t scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx)
1963{ 1959{
1964 struct request_queue *q = hctx->queue; 1960 struct request_queue *q = hctx->queue;
1965 struct scsi_device *sdev = q->queuedata; 1961 struct scsi_device *sdev = q->queuedata;
1966 struct Scsi_Host *shost = sdev->host;
1967 blk_status_t ret; 1962 blk_status_t ret;
1968 1963
1969 ret = prep_to_mq(scsi_prep_state_check(sdev, NULL)); 1964 ret = prep_to_mq(scsi_prep_state_check(sdev, NULL));
@@ -1974,18 +1969,9 @@ static blk_status_t scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx)
1974 goto out; 1969 goto out;
1975 if (!scsi_dev_queue_ready(q, sdev)) 1970 if (!scsi_dev_queue_ready(q, sdev))
1976 goto out_put_device; 1971 goto out_put_device;
1977 if (!scsi_target_queue_ready(shost, sdev))
1978 goto out_dec_device_busy;
1979 if (!scsi_host_queue_ready(q, shost, sdev))
1980 goto out_dec_target_busy;
1981 1972
1982 return BLK_STS_OK; 1973 return BLK_STS_OK;
1983 1974
1984out_dec_target_busy:
1985 if (scsi_target(sdev)->can_queue > 0)
1986 atomic_dec(&scsi_target(sdev)->target_busy);
1987out_dec_device_busy:
1988 atomic_dec(&sdev->device_busy);
1989out_put_device: 1975out_put_device:
1990 put_device(&sdev->sdev_gendev); 1976 put_device(&sdev->sdev_gendev);
1991out: 1977out:
@@ -1998,6 +1984,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
1998 struct request *req = bd->rq; 1984 struct request *req = bd->rq;
1999 struct request_queue *q = req->q; 1985 struct request_queue *q = req->q;
2000 struct scsi_device *sdev = q->queuedata; 1986 struct scsi_device *sdev = q->queuedata;
1987 struct Scsi_Host *shost = sdev->host;
2001 struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); 1988 struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
2002 blk_status_t ret; 1989 blk_status_t ret;
2003 int reason; 1990 int reason;
@@ -2007,10 +1994,15 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
2007 goto out_put_budget; 1994 goto out_put_budget;
2008 1995
2009 ret = BLK_STS_RESOURCE; 1996 ret = BLK_STS_RESOURCE;
1997 if (!scsi_target_queue_ready(shost, sdev))
1998 goto out_put_budget;
1999 if (!scsi_host_queue_ready(q, shost, sdev))
2000 goto out_dec_target_busy;
2001
2010 if (!(req->rq_flags & RQF_DONTPREP)) { 2002 if (!(req->rq_flags & RQF_DONTPREP)) {
2011 ret = prep_to_mq(scsi_mq_prep_fn(req)); 2003 ret = prep_to_mq(scsi_mq_prep_fn(req));
2012 if (ret != BLK_STS_OK) 2004 if (ret != BLK_STS_OK)
2013 goto out_put_budget; 2005 goto out_dec_host_busy;
2014 req->rq_flags |= RQF_DONTPREP; 2006 req->rq_flags |= RQF_DONTPREP;
2015 } else { 2007 } else {
2016 blk_mq_start_request(req); 2008 blk_mq_start_request(req);
@@ -2028,11 +2020,16 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
2028 if (reason) { 2020 if (reason) {
2029 scsi_set_blocked(cmd, reason); 2021 scsi_set_blocked(cmd, reason);
2030 ret = BLK_STS_RESOURCE; 2022 ret = BLK_STS_RESOURCE;
2031 goto out_put_budget; 2023 goto out_dec_host_busy;
2032 } 2024 }
2033 2025
2034 return BLK_STS_OK; 2026 return BLK_STS_OK;
2035 2027
2028out_dec_host_busy:
2029 atomic_dec(&shost->host_busy);
2030out_dec_target_busy:
2031 if (scsi_target(sdev)->can_queue > 0)
2032 atomic_dec(&scsi_target(sdev)->target_busy);
2036out_put_budget: 2033out_put_budget:
2037 scsi_mq_put_budget(hctx); 2034 scsi_mq_put_budget(hctx);
2038 switch (ret) { 2035 switch (ret) {