Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bdd17e75 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKeith Busch <keith.busch@intel.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 4e68a011
Loading
Loading
Loading
Loading
+14 −8
Original line number Original line Diff line number Diff line
@@ -1973,7 +1973,6 @@ void blk_mq_release(struct request_queue *q)
		kfree(hctx);
		kfree(hctx);
	}
	}


	kfree(q->mq_map);
	q->mq_map = NULL;
	q->mq_map = NULL;


	kfree(q->queue_hw_ctx);
	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)
	if (!q->queue_hw_ctx)
		goto err_percpu;
		goto err_percpu;


	q->mq_map = blk_mq_make_queue_map(set);
	q->mq_map = set->mq_map;
	if (!q->mq_map)
		goto err_map;


	blk_mq_realloc_hw_ctxs(set, q);
	blk_mq_realloc_hw_ctxs(set, q);
	if (!q->nr_hw_queues)
	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;
	return q;


err_hctxs:
err_hctxs:
	kfree(q->mq_map);
err_map:
	kfree(q->queue_hw_ctx);
	kfree(q->queue_hw_ctx);
err_percpu:
err_percpu:
	free_percpu(q->queue_ctx);
	free_percpu(q->queue_ctx);
@@ -2347,14 +2342,22 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set)
	if (!set->tags)
	if (!set->tags)
		return -ENOMEM;
		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))
	if (blk_mq_alloc_rq_maps(set))
		goto enomem;
		goto out_free_mq_map;


	mutex_init(&set->tag_list_lock);
	mutex_init(&set->tag_list_lock);
	INIT_LIST_HEAD(&set->tag_list);
	INIT_LIST_HEAD(&set->tag_list);


	return 0;
	return 0;
enomem:

out_free_mq_map:
	kfree(set->mq_map);
	set->mq_map = NULL;
out_free_tags:
	kfree(set->tags);
	kfree(set->tags);
	set->tags = NULL;
	set->tags = NULL;
	return -ENOMEM;
	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);
			blk_mq_free_rq_map(set, set->tags[i], i);
	}
	}


	kfree(set->mq_map);
	set->mq_map = NULL;

	kfree(set->tags);
	kfree(set->tags);
	set->tags = NULL;
	set->tags = NULL;
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -67,6 +67,7 @@ struct blk_mq_hw_ctx {
};
};


struct blk_mq_tag_set {
struct blk_mq_tag_set {
	unsigned int		*mq_map;
	struct blk_mq_ops	*ops;
	struct blk_mq_ops	*ops;
	unsigned int		nr_hw_queues;
	unsigned int		nr_hw_queues;
	unsigned int		queue_depth;	/* max hw supported */
	unsigned int		queue_depth;	/* max hw supported */