cgroup: fix offlining child waiting in cgroup_subtree_control_write()
cgroup_subtree_control_write() waits for offline to complete child-by-child before enabling a controller; however, it has a couple bugs. * It doesn't initialize the wait_queue_t. This can lead to infinite hang on the following schedule() among other things. * It forgets to pin the child before releasing cgroup_tree_mutex and performing schedule(). The child may already be gone by the time it wakes up and invokes finish_wait(). Pin the child being waited on. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
This commit is contained in:
parent
f21a4f7594
commit
0cee8b7786
1 changed files with 3 additions and 1 deletions
|
@ -2594,16 +2594,18 @@ retry:
|
||||||
* cases, wait till it's gone using offline_waitq.
|
* cases, wait till it's gone using offline_waitq.
|
||||||
*/
|
*/
|
||||||
cgroup_for_each_live_child(child, cgrp) {
|
cgroup_for_each_live_child(child, cgrp) {
|
||||||
wait_queue_t wait;
|
DEFINE_WAIT(wait);
|
||||||
|
|
||||||
if (!cgroup_css(child, ss))
|
if (!cgroup_css(child, ss))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
cgroup_get(child);
|
||||||
prepare_to_wait(&child->offline_waitq, &wait,
|
prepare_to_wait(&child->offline_waitq, &wait,
|
||||||
TASK_UNINTERRUPTIBLE);
|
TASK_UNINTERRUPTIBLE);
|
||||||
mutex_unlock(&cgroup_tree_mutex);
|
mutex_unlock(&cgroup_tree_mutex);
|
||||||
schedule();
|
schedule();
|
||||||
finish_wait(&child->offline_waitq, &wait);
|
finish_wait(&child->offline_waitq, &wait);
|
||||||
|
cgroup_put(child);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue