diff options
author | Tejun Heo <tj@kernel.org> | 2014-11-18 02:49:50 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-11-18 02:49:50 -0500 |
commit | 755bf5ee8633b97d8fd0ffbb4221662056dda22b (patch) | |
tree | 5b2a32ce799333ccf8db0a7ffdc0e0df7be2e695 /kernel/cgroup.c | |
parent | 0f060deb5c5107486c5dadd5c715b3693d381e0a (diff) |
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>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 1dda601ec337..cbbb46f783de 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -2653,7 +2653,7 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, | |||
2653 | loff_t off) | 2653 | loff_t off) |
2654 | { | 2654 | { |
2655 | unsigned int enable = 0, disable = 0; | 2655 | unsigned int enable = 0, disable = 0; |
2656 | unsigned int css_enable, css_disable, old_ctrl, new_ctrl; | 2656 | unsigned int css_enable, css_disable, old_sc, new_sc, old_ss, new_ss; |
2657 | struct cgroup *cgrp, *child; | 2657 | struct cgroup *cgrp, *child; |
2658 | struct cgroup_subsys *ss; | 2658 | struct cgroup_subsys *ss; |
2659 | char *tok; | 2659 | char *tok; |
@@ -2770,18 +2770,19 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, | |||
2770 | * subsystems than specified may need to be enabled or disabled | 2770 | * subsystems than specified may need to be enabled or disabled |
2771 | * depending on subsystem dependencies. | 2771 | * depending on subsystem dependencies. |
2772 | */ | 2772 | */ |
2773 | cgrp->subtree_control |= enable; | 2773 | old_sc = cgrp->subtree_control; |
2774 | cgrp->subtree_control &= ~disable; | 2774 | old_ss = cgrp->child_subsys_mask; |
2775 | new_sc = (old_sc | enable) & ~disable; | ||
2776 | new_ss = cgroup_calc_child_subsys_mask(cgrp, new_sc); | ||
2775 | 2777 | ||
2776 | old_ctrl = cgrp->child_subsys_mask; | 2778 | css_enable = ~old_ss & new_ss; |
2777 | cgroup_refresh_child_subsys_mask(cgrp); | 2779 | css_disable = old_ss & ~new_ss; |
2778 | new_ctrl = cgrp->child_subsys_mask; | ||
2779 | |||
2780 | css_enable = ~old_ctrl & new_ctrl; | ||
2781 | css_disable = old_ctrl & ~new_ctrl; | ||
2782 | enable |= css_enable; | 2780 | enable |= css_enable; |
2783 | disable |= css_disable; | 2781 | disable |= css_disable; |
2784 | 2782 | ||
2783 | cgrp->subtree_control = new_sc; | ||
2784 | cgrp->child_subsys_mask = new_ss; | ||
2785 | |||
2785 | /* | 2786 | /* |
2786 | * Create new csses or make the existing ones visible. A css is | 2787 | * Create new csses or make the existing ones visible. A css is |
2787 | * created invisible if it's being implicitly enabled through | 2788 | * created invisible if it's being implicitly enabled through |
@@ -2844,9 +2845,8 @@ out_unlock: | |||
2844 | return ret ?: nbytes; | 2845 | return ret ?: nbytes; |
2845 | 2846 | ||
2846 | err_undo_css: | 2847 | err_undo_css: |
2847 | cgrp->subtree_control &= ~enable; | 2848 | cgrp->subtree_control = old_sc; |
2848 | cgrp->subtree_control |= disable; | 2849 | cgrp->child_subsys_mask = old_ss; |
2849 | cgroup_refresh_child_subsys_mask(cgrp); | ||
2850 | 2850 | ||
2851 | for_each_subsys(ss, ssid) { | 2851 | for_each_subsys(ss, ssid) { |
2852 | if (!(enable & (1 << ssid))) | 2852 | if (!(enable & (1 << ssid))) |