From: Yu Kuai yukuai3@huawei.com
hulk inclusion category: bugfix bugzilla: 174635 CVE: NA
-----------------------------------------------
If blkg creation concurrent with device removal, queue ref might be unbalanced:
t1 t2 t3 cgroup_file_write blkg_conf_prep q = disk->queue dm_ctl_ioctl dev_remove blk_cleanup_queue queue_flag_set(QUEUE_FLAG_DYING, q) blkg_alloc blk_init_cl blk_get_queue -> failed blk_exit_queue blkcg_exit_queue blkg_destroy_all blkg_destroy call_rcu(&blkg->rcu_head, __blkg_release_rcu);
__blkg_release_rcu blkg_free blk_exit_rl blk_put_queue -> extra put
Thus error out if blk_get_queue() failed in blk_init_rl(), since there is no need to create blkg while queue is dying.
Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Hou Tao houtao1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- block/blk-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/block/blk-core.c b/block/blk-core.c index 93970be37c17c..4b63336465306 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -888,8 +888,11 @@ int blk_init_rl(struct request_list *rl, struct request_queue *q, if (!rl->rq_pool) return -ENOMEM;
- if (rl != &q->root_rl) - WARN_ON_ONCE(!blk_get_queue(q)); + if (rl != &q->root_rl && !blk_get_queue(q)) { + mempool_destroy(rl->rq_pool); + rl->rq_pool = NULL; + return -ENODEV; + }
return 0; }