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 | |
| 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')
| -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))) |
