[PATCH V7 6/6] SCSI: implement .get_budget and .put_budget for blk-mq
From: Ming Lei <hidden>
Date: 2017-10-12 18:39:27
Also in:
linux-scsi, lkml
Subsystem:
scsi subsystem, the rest · Maintainers:
"James E.J. Bottomley", "Martin K. Petersen", Linus Torvalds
We need to tell blk-mq to reserve resource before queuing one request, so implement these two callbacks. Then blk-mq can avoid to dequeue request earlier, and IO merge can be improved a lot. Signed-off-by: Ming Lei <redacted> --- drivers/scsi/scsi_lib.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9cf6a80fe297..d6273954a3b4 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c@@ -1946,6 +1946,33 @@ static void scsi_mq_done(struct scsi_cmnd *cmd) blk_mq_complete_request(cmd->request); } +static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx) +{ + struct request_queue *q = hctx->queue; + struct scsi_device *sdev = q->queuedata; + + atomic_dec(&sdev->device_busy); + put_device(&sdev->sdev_gendev); +} + +static bool scsi_mq_get_budget(struct blk_mq_hw_ctx *hctx) +{ + struct request_queue *q = hctx->queue; + struct scsi_device *sdev = q->queuedata; + + if (!get_device(&sdev->sdev_gendev)) + goto out; + if (!scsi_dev_queue_ready(q, sdev)) + goto out_put_device; + + return true; + +out_put_device: + put_device(&sdev->sdev_gendev); +out: + return false; +} + static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) {
@@ -1962,13 +1989,8 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, goto out; ret = BLK_STS_RESOURCE; - if (!get_device(&sdev->sdev_gendev)) - goto out; - - if (!scsi_dev_queue_ready(q, sdev)) - goto out_put_device; if (!scsi_target_queue_ready(shost, sdev)) - goto out_dec_device_busy; + goto out_put_budget; if (!scsi_host_queue_ready(q, shost, sdev)) goto out_dec_target_busy;
@@ -2003,10 +2025,8 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, out_dec_target_busy: if (scsi_target(sdev)->can_queue > 0) atomic_dec(&scsi_target(sdev)->target_busy); -out_dec_device_busy: - atomic_dec(&sdev->device_busy); -out_put_device: - put_device(&sdev->sdev_gendev); +out_put_budget: + scsi_mq_put_budget(hctx); out: switch (ret) { case BLK_STS_OK:
@@ -2211,6 +2231,8 @@ struct request_queue *scsi_old_alloc_queue(struct scsi_device *sdev) } static const struct blk_mq_ops scsi_mq_ops = { + .get_budget = scsi_mq_get_budget, + .put_budget = scsi_mq_put_budget, .queue_rq = scsi_queue_rq, .complete = scsi_softirq_done, .timeout = scsi_timeout,
--
2.9.5