Message ID | 20230821095602.70742-1-chengming.zhou@linux.dev (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/3] blk-mq: fix tags leak when shrink nr_hw_queues | expand |
On Mon, Aug 21, 2023 at 05:56:00PM +0800, chengming.zhou@linux.dev wrote: > From: Chengming Zhou <zhouchengming@bytedance.com> > > Although we don't need to realloc set->tags[] when shrink nr_hw_queues, > we need to free them. Or these tags will be leaked. > > How to reproduce: > 1. mount -t configfs configfs /mnt > 2. modprobe null_blk nr_devices=0 submit_queues=8 > 3. mkdir /mnt/nullb/nullb0 > 4. echo 1 > /mnt/nullb/nullb0/power > 5. echo 4 > /mnt/nullb/nullb0/submit_queues > 6. rmdir /mnt/nullb/nullb0 > > In step 4, will alloc 9 tags (8 submit queues and 1 poll queue), then > in step 5, new_nr_hw_queues = 5 (4 submit queues and 1 poll queue). > At last in step 6, only these 5 tags are freed, the other 4 tags leaked. > > Signed-off-by: Chengming Zhou <zhouchengming@bytedance.com> Reviewed-by: Ming Lei <ming.lei@redhat.com>
On Mon, 21 Aug 2023 17:56:00 +0800, chengming.zhou@linux.dev wrote: > Although we don't need to realloc set->tags[] when shrink nr_hw_queues, > we need to free them. Or these tags will be leaked. > > How to reproduce: > 1. mount -t configfs configfs /mnt > 2. modprobe null_blk nr_devices=0 submit_queues=8 > 3. mkdir /mnt/nullb/nullb0 > 4. echo 1 > /mnt/nullb/nullb0/power > 5. echo 4 > /mnt/nullb/nullb0/submit_queues > 6. rmdir /mnt/nullb/nullb0 > > [...] Applied, thanks! [1/3] blk-mq: fix tags leak when shrink nr_hw_queues commit: e1dd7bc93029024af5688253b0c05181d6e01f8e [2/3] blk-mq: delete redundant tagset map update when fallback commit: 2bc4d7a355a4d617452eaf1b21d6d261194b3667 [3/3] blk-mq: prealloc tags when increase tagset nr_hw_queues commit: 7222657e51b5626d10154b3e48ad441c33b5da96 Best regards,
diff --git a/block/blk-mq.c b/block/blk-mq.c index f14b8669ac69..8af29a3b1400 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -4386,9 +4386,13 @@ static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set, int new_nr_hw_queues) { struct blk_mq_tags **new_tags; + int i; - if (set->nr_hw_queues >= new_nr_hw_queues) + if (set->nr_hw_queues >= new_nr_hw_queues) { + for (i = new_nr_hw_queues; i < set->nr_hw_queues; i++) + __blk_mq_free_map_and_rqs(set, i); goto done; + } new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *), GFP_KERNEL, set->numa_node);