cgroup: restructure child_subsys_mask handling in cgroup_subtree_control_write()
Make cgroup_subtree_control_write() first calculate new subtree_control (new_sc), child_subsys_mask (new_ss) and css_enable/disable masks before applying them to the cgroup. Also, store the original subtree_control (old_sc) and child_subsys_mask (old_ss) and use them to restore the orignal state after failure. This patch shouldn't cause any behavior changes. This prepares for a fix for a bug in the async css offline wait logic. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Zefan Li <lizefan@huawei.com>
This commit is contained in:
parent
0f060deb5c
commit
755bf5ee86
@ -2653,7 +2653,7 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
|
|||||||
loff_t off)
|
loff_t off)
|
||||||
{
|
{
|
||||||
unsigned int enable = 0, disable = 0;
|
unsigned int enable = 0, disable = 0;
|
||||||
unsigned int css_enable, css_disable, old_ctrl, new_ctrl;
|
unsigned int css_enable, css_disable, old_sc, new_sc, old_ss, new_ss;
|
||||||
struct cgroup *cgrp, *child;
|
struct cgroup *cgrp, *child;
|
||||||
struct cgroup_subsys *ss;
|
struct cgroup_subsys *ss;
|
||||||
char *tok;
|
char *tok;
|
||||||
@ -2770,18 +2770,19 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
|
|||||||
* subsystems than specified may need to be enabled or disabled
|
* subsystems than specified may need to be enabled or disabled
|
||||||
* depending on subsystem dependencies.
|
* depending on subsystem dependencies.
|
||||||
*/
|
*/
|
||||||
cgrp->subtree_control |= enable;
|
old_sc = cgrp->subtree_control;
|
||||||
cgrp->subtree_control &= ~disable;
|
old_ss = cgrp->child_subsys_mask;
|
||||||
|
new_sc = (old_sc | enable) & ~disable;
|
||||||
|
new_ss = cgroup_calc_child_subsys_mask(cgrp, new_sc);
|
||||||
|
|
||||||
old_ctrl = cgrp->child_subsys_mask;
|
css_enable = ~old_ss & new_ss;
|
||||||
cgroup_refresh_child_subsys_mask(cgrp);
|
css_disable = old_ss & ~new_ss;
|
||||||
new_ctrl = cgrp->child_subsys_mask;
|
|
||||||
|
|
||||||
css_enable = ~old_ctrl & new_ctrl;
|
|
||||||
css_disable = old_ctrl & ~new_ctrl;
|
|
||||||
enable |= css_enable;
|
enable |= css_enable;
|
||||||
disable |= css_disable;
|
disable |= css_disable;
|
||||||
|
|
||||||
|
cgrp->subtree_control = new_sc;
|
||||||
|
cgrp->child_subsys_mask = new_ss;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create new csses or make the existing ones visible. A css is
|
* Create new csses or make the existing ones visible. A css is
|
||||||
* created invisible if it's being implicitly enabled through
|
* created invisible if it's being implicitly enabled through
|
||||||
@ -2844,9 +2845,8 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
|
|||||||
return ret ?: nbytes;
|
return ret ?: nbytes;
|
||||||
|
|
||||||
err_undo_css:
|
err_undo_css:
|
||||||
cgrp->subtree_control &= ~enable;
|
cgrp->subtree_control = old_sc;
|
||||||
cgrp->subtree_control |= disable;
|
cgrp->child_subsys_mask = old_ss;
|
||||||
cgroup_refresh_child_subsys_mask(cgrp);
|
|
||||||
|
|
||||||
for_each_subsys(ss, ssid) {
|
for_each_subsys(ss, ssid) {
|
||||||
if (!(enable & (1 << ssid)))
|
if (!(enable & (1 << ssid)))
|
||||||
|
Loading…
Reference in New Issue
Block a user