summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorJiang Biao <jiang.biao2@zte.com.cn>2018-04-19 12:06:09 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-06-21 04:02:44 +0900
commitea7246c258922565a53319ddc54684d081d1b4c8 (patch)
tree16eb152c335e9d9335cf7a448aef7abbeb188cd1 /block
parentb6126afd64d069384e41605779e8e27288185359 (diff)
blkcg: init root blkcg_gq under lock
[ Upstream commit 901932a3f9b2b80352896be946c6d577c0a9652c ] The initializing of q->root_blkg is currently outside of queue lock and rcu, so the blkg may be destroied before the initializing, which may cause dangling/null references. On the other side, the destroys of blkg are protected by queue lock or rcu. Put the initializing inside the queue lock and rcu to make it safer. Signed-off-by: Jiang Biao <jiang.biao2@zte.com.cn> Signed-off-by: Wen Yang <wen.yang99@zte.com.cn> CC: Tejun Heo <tj@kernel.org> CC: Jens Axboe <axboe@kernel.dk> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'block')
-rw-r--r--block/blk-cgroup.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 00b133c44474..3dc7c0b4adcb 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -1149,18 +1149,16 @@ int blkcg_init_queue(struct request_queue *q)
rcu_read_lock();
spin_lock_irq(q->queue_lock);
blkg = blkg_create(&blkcg_root, q, new_blkg);
+ if (IS_ERR(blkg))
+ goto err_unlock;
+ q->root_blkg = blkg;
+ q->root_rl.blkg = blkg;
spin_unlock_irq(q->queue_lock);
rcu_read_unlock();
if (preloaded)
radix_tree_preload_end();
- if (IS_ERR(blkg))
- return PTR_ERR(blkg);
-
- q->root_blkg = blkg;
- q->root_rl.blkg = blkg;
-
ret = blk_throtl_init(q);
if (ret) {
spin_lock_irq(q->queue_lock);
@@ -1168,6 +1166,13 @@ int blkcg_init_queue(struct request_queue *q)
spin_unlock_irq(q->queue_lock);
}
return ret;
+
+err_unlock:
+ spin_unlock_irq(q->queue_lock);
+ rcu_read_unlock();
+ if (preloaded)
+ radix_tree_preload_end();
+ return PTR_ERR(blkg);
}
/**