diff options
author | Christoph Hellwig <hch@lst.de> | 2016-09-14 16:18:53 +0200 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2016-09-15 08:42:03 -0600 |
commit | bdd17e75cd97c5c39feee409890a91d0396640fe (patch) | |
tree | a7b6b01aa305d466e83255caa08670391c294b33 | |
parent | 4e68a011428af3211facd932b4003b3fa3ef4faa (diff) | |
download | linux-stable-bdd17e75cd97c5c39feee409890a91d0396640fe.tar.gz linux-stable-bdd17e75cd97c5c39feee409890a91d0396640fe.tar.bz2 linux-stable-bdd17e75cd97c5c39feee409890a91d0396640fe.zip |
blk-mq: only allocate a single mq_map per tag_set
The mapping is identical for all queues in a tag_set, so stop wasting
memory for building multiple. Note that for now I've kept the mq_map
pointer in the request_queue, but we'll need to investigate if we can
remove it without suffering too much from the additional pointer chasing.
The same would apply to the mq_ops pointer as well.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-mq.c | 22 | ||||
-rw-r--r-- | include/linux/blk-mq.h | 1 |
2 files changed, 15 insertions, 8 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index ffc9d4a3dbbd..c9499f118ef6 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1973,7 +1973,6 @@ void blk_mq_release(struct request_queue *q) kfree(hctx); } - kfree(q->mq_map); q->mq_map = NULL; kfree(q->queue_hw_ctx); @@ -2072,9 +2071,7 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, if (!q->queue_hw_ctx) goto err_percpu; - q->mq_map = blk_mq_make_queue_map(set); - if (!q->mq_map) - goto err_map; + q->mq_map = set->mq_map; blk_mq_realloc_hw_ctxs(set, q); if (!q->nr_hw_queues) @@ -2124,8 +2121,6 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, return q; err_hctxs: - kfree(q->mq_map); -err_map: kfree(q->queue_hw_ctx); err_percpu: free_percpu(q->queue_ctx); @@ -2347,14 +2342,22 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) if (!set->tags) return -ENOMEM; + set->mq_map = blk_mq_make_queue_map(set); + if (!set->mq_map) + goto out_free_tags; + if (blk_mq_alloc_rq_maps(set)) - goto enomem; + goto out_free_mq_map; mutex_init(&set->tag_list_lock); INIT_LIST_HEAD(&set->tag_list); return 0; -enomem: + +out_free_mq_map: + kfree(set->mq_map); + set->mq_map = NULL; +out_free_tags: kfree(set->tags); set->tags = NULL; return -ENOMEM; @@ -2370,6 +2373,9 @@ void blk_mq_free_tag_set(struct blk_mq_tag_set *set) blk_mq_free_rq_map(set, set->tags[i], i); } + kfree(set->mq_map); + set->mq_map = NULL; + kfree(set->tags); set->tags = NULL; } diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 60ef14cbcd2d..deda16a9bde4 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -67,6 +67,7 @@ struct blk_mq_hw_ctx { }; struct blk_mq_tag_set { + unsigned int *mq_map; struct blk_mq_ops *ops; unsigned int nr_hw_queues; unsigned int queue_depth; /* max hw supported */ |