blk-mq: fix leak of hctx->ctx_map
cover blk-mq: fix leak of hctx->ctx_map
Misc changes.
Thanks,
--
Ming Lei
PATCH 1/3 blk-mq: fix leak of hctx->ctx_map
hctx->ctx_map should have been freed inside blk_mq_free_queue().
--- block/blk-mq.c | 1 + 1 file changed, 1 insertion(+)
block/blk-mq.c +1 -0
@@ -1841,6 +1841,7 @@ void blk_mq_free_queue(struct request_queue *q)queue_for_each_hw_ctx (q, hctx, i) {kfree (hctx->ctxs); +blk_mq_free_bitmap (&hctx->ctx_map);blk_mq_unregister_cpu_notifier (&hctx->cpu_notifier);if (q->mq_ops->exit_hctx) q->mq_ops->exit_hctx (hctx, i);
Signature · 1 line
1.7.9.5
PATCH 2/3 blk-mq: avoid code duplication
In reply to Ming Leiblk_mq_exit_hw_queues() and blk_mq_free_hw_queues() are introduced to avoid code duplication.
--- block/blk-mq.c | 60 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 23 deletions(-)
block/blk-mq.c +37 -23
@@ -1519,11 +1519,43 @@ static int blk_mq_hctx_notify(void *data, unsigned long action,return NOTIFY_OK ; } +static void blk_mq_exit_hw_queues (struct request_queue *q, +struct blk_mq_tag_set *set,int nr_queue) +{ +struct blk_mq_hw_ctx *hctx; +unsigned int i; + +queue_for_each_hw_ctx (q, hctx, i) { +if (i == nr_queue) +break ; + +if (set->ops->exit_hctx) + set->ops->exit_hctx (hctx, i); + +blk_mq_unregister_cpu_notifier (&hctx->cpu_notifier); +kfree (hctx->ctxs); +blk_mq_free_bitmap (&hctx->ctx_map); + } + +} + +static void blk_mq_free_hw_queues (struct request_queue *q, +struct blk_mq_tag_set *set) +{ +struct blk_mq_hw_ctx *hctx; +unsigned int i; + +queue_for_each_hw_ctx (q, hctx, i) { +free_cpumask_var (hctx->cpumask); + set->ops->free_hctx (hctx, i); + } +} +static int blk_mq_init_hw_queues (struct request_queue *q,struct blk_mq_tag_set *set) {struct blk_mq_hw_ctx *hctx; -unsigned int i, j; +unsigned int i;/* * Initialize hardware queues
@@ -1575,17 +1607,7 @@ static int blk_mq_init_hw_queues(struct request_queue *q,/* * Init failed */ -queue_for_each_hw_ctx (q, hctx, j) { -if (i == j) -break ; - -if (set->ops->exit_hctx) - set->ops->exit_hctx (hctx, j); - -blk_mq_unregister_cpu_notifier (&hctx->cpu_notifier); -kfree (hctx->ctxs); -blk_mq_free_bitmap (&hctx->ctx_map); - } +blk_mq_exit_hw_queues (q, set, i);return 1 ; }
@@ -1834,20 +1856,12 @@ EXPORT_SYMBOL(blk_mq_init_queue);void blk_mq_free_queue (struct request_queue *q) { -struct blk_mq_hw_ctx *hctx; -int i; +struct blk_mq_tag_set *set = q->tag_set;blk_mq_del_queue_tag_set (q); -queue_for_each_hw_ctx (q, hctx, i) { -kfree (hctx->ctxs); -blk_mq_free_bitmap (&hctx->ctx_map); -blk_mq_unregister_cpu_notifier (&hctx->cpu_notifier); -if (q->mq_ops->exit_hctx) - q->mq_ops->exit_hctx (hctx, i); -free_cpumask_var (hctx->cpumask); - q->mq_ops->free_hctx (hctx, i); - } +blk_mq_exit_hw_queues (q, set, set->nr_hw_queues); +blk_mq_free_hw_queues (q, set);free_percpu (q->queue_ctx);kfree (q->queue_hw_ctx);
Signature · 1 line
1.7.9.5
PATCH 3/3 block: only allocate/free mq_usage_counter in blk-mq
In reply to Ming LeiThe percpu counter is only used for blk-mq, so move its allocation and free inside blk-mq, and don't allocate it for legacy queue device.
--- block/blk-core.c | 7 +------ block/blk-mq.c | 5 +++++ block/blk-sysfs.c | 2 -- 3 files changed, 6 insertions(+), 8 deletions(-)
block/blk-core.c +1 -6
@@ -576,12 +576,9 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)if (!q)return NULL ; -if (percpu_counter_init (&q->mq_usage_counter,0 )) - goto fail_q; - q->id =ida_simple_get (&blk_queue_ida,0 ,0 , gfp_mask);if (q->id <0 ) - goto fail_c; + goto fail_q; q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD *1024 ) /PAGE_CACHE_SIZE ;
@@ -639,8 +636,6 @@ fail_bdi:bdi_destroy (&q->backing_dev_info); fail_id:ida_simple_remove (&blk_queue_ida, q->id); -fail_c: -percpu_counter_destroy (&q->mq_usage_counter); fail_q:kmem_cache_free (blk_requestq_cachep, q);return NULL ;
block/blk-mq.c +5 -0
@@ -1777,6 +1777,9 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)if (!q) goto err_hctxs; +if (percpu_counter_init (&q->mq_usage_counter,0 )) + goto err_map; + q->mq_map =blk_mq_make_queue_map (set);if (!q->mq_map) goto err_map;
@@ -1863,6 +1866,8 @@ void blk_mq_free_queue(struct request_queue *q)blk_mq_exit_hw_queues (q, set, set->nr_hw_queues);blk_mq_free_hw_queues (q, set); +percpu_counter_destroy (&q->mq_usage_counter); +free_percpu (q->queue_ctx);kfree (q->queue_hw_ctx);kfree (q->mq_map);
block/blk-sysfs.c +0 -2
@@ -517,8 +517,6 @@ static void blk_release_queue(struct kobject *kobj)if (q->queue_tags)__blk_queue_free_tags (q); -percpu_counter_destroy (&q->mq_usage_counter); -if (q->mq_ops)blk_mq_free_queue (q);
Signature · 1 line
1.7.9.5
Jens Axboe
maintainerQuoted 1 line · Ming Lei
Misc changes.
All look good, however they don't apply to the current for-3.16/core branch. What are they against? I hand applied 1, but could you regenerate 2+3 against the current tree?
Signature · 1 line
Jens Axboe
Quoted 6 lines · Jens Axboe
Quoted 1 line · Ming Lei
Misc changes.
All look good, however they don't apply to the current for-3.16/core branch. What are they against? I hand applied 1, but could you regenerate 2+3 against the current tree?
It is against your tree several days ago, and will resend the 2nd and 3rd out.
Thanks,
Signature · 1 line
Ming Lei