summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2017-01-26 22:32:32 +0300
committerJens Axboe <axboe@fb.com>2017-01-27 18:20:32 +0300
commit99cf1dc580f0766825395aae4f60ec1d8438f011 (patch)
treeaba73ea31e8835977afc3c7291af3233afed7113
parent3c782d67c16889d753a79a8da5422c583d7cfd51 (diff)
downloadlinux-99cf1dc580f0766825395aae4f60ec1d8438f011.tar.xz
blk-mq: release driver tag on a requeue event
We don't want to hold on to this resource when we have a scheduler attached. Signed-off-by: Jens Axboe <axboe@fb.com> Reviewed-by: Omar Sandoval <osandov@fb.com> Tested-by: Hannes Reinecke <hare@suse.com>
-rw-r--r--block/blk-mq.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c
index fd80101c7591..711883384585 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -879,6 +879,21 @@ done:
return false;
}
+static void blk_mq_put_driver_tag(struct blk_mq_hw_ctx *hctx,
+ struct request *rq)
+{
+ if (rq->tag == -1 || rq->internal_tag == -1)
+ return;
+
+ blk_mq_put_tag(hctx, hctx->tags, rq->mq_ctx, rq->tag);
+ rq->tag = -1;
+
+ if (rq->rq_flags & RQF_MQ_INFLIGHT) {
+ rq->rq_flags &= ~RQF_MQ_INFLIGHT;
+ atomic_dec(&hctx->nr_active);
+ }
+}
+
/*
* If we fail getting a driver tag because all the driver tags are already
* assigned and on the dispatch list, BUT the first entry does not have a
@@ -951,6 +966,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list)
queued++;
break;
case BLK_MQ_RQ_QUEUE_BUSY:
+ blk_mq_put_driver_tag(hctx, rq);
list_add(&rq->queuelist, list);
__blk_mq_requeue_request(rq);
break;