diff options
author | Tejun Heo <tj@kernel.org> | 2016-03-03 09:57:59 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2016-03-03 09:57:59 -0500 |
commit | bdb53bd797dcef46d1a252b9529f8fd511bf714c (patch) | |
tree | 28d344a6ebeecc252596933257412a92f3ab1626 | |
parent | 12b3bb6af862477f96e1adac51b201a143a8f3c4 (diff) |
cgroup: factor out cgroup_apply_control_enable() from cgroup_subtree_control_write()
Factor out css enabling and showing into cgroup_apply_control_enable().
* Nest subsystem walk inside child walk. The child walk will later be
converted to subtree walk which is a bit more expensive.
* Instead of operating on the differential masks @css_enable, simply
enable or show csses according to the current cgroup_control() and
cgroup_ss_mask(). This leads to the same result and is simpler and
more robust.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Zefan Li <lizefan@huawei.com>
-rw-r--r-- | kernel/cgroup.c | 77 |
1 files changed, 47 insertions, 30 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 97cb1315bcac..1193038d0729 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -3013,6 +3013,49 @@ static bool cgroup_drain_offline(struct cgroup *cgrp) | |||
3013 | } | 3013 | } |
3014 | 3014 | ||
3015 | /** | 3015 | /** |
3016 | * cgroup_apply_control_enable - enable or show csses according to control | ||
3017 | * @cgrp: parent of the target cgroups | ||
3018 | * | ||
3019 | * Walk @cgrp's children and create new csses or make the existing ones | ||
3020 | * visible. A css is created invisible if it's being implicitly enabled | ||
3021 | * through dependency. An invisible css is made visible when the userland | ||
3022 | * explicitly enables it. | ||
3023 | * | ||
3024 | * Returns 0 on success, -errno on failure. On failure, csses which have | ||
3025 | * been processed already aren't cleaned up. The caller is responsible for | ||
3026 | * cleaning up with cgroup_apply_control_disble(). | ||
3027 | */ | ||
3028 | static int cgroup_apply_control_enable(struct cgroup *cgrp) | ||
3029 | { | ||
3030 | struct cgroup *dsct; | ||
3031 | struct cgroup_subsys *ss; | ||
3032 | int ssid, ret; | ||
3033 | |||
3034 | cgroup_for_each_live_child(dsct, cgrp) { | ||
3035 | for_each_subsys(ss, ssid) { | ||
3036 | struct cgroup_subsys_state *css = cgroup_css(dsct, ss); | ||
3037 | |||
3038 | if (!(cgroup_ss_mask(dsct) & (1 << ss->id))) | ||
3039 | continue; | ||
3040 | |||
3041 | if (!css) { | ||
3042 | css = css_create(dsct, ss); | ||
3043 | if (IS_ERR(css)) | ||
3044 | return PTR_ERR(css); | ||
3045 | } | ||
3046 | |||
3047 | if (cgroup_control(dsct) & (1 << ss->id)) { | ||
3048 | ret = css_populate_dir(css, NULL); | ||
3049 | if (ret) | ||
3050 | return ret; | ||
3051 | } | ||
3052 | } | ||
3053 | } | ||
3054 | |||
3055 | return 0; | ||
3056 | } | ||
3057 | |||
3058 | /** | ||
3016 | * cgroup_apply_control_disable - kill or hide csses according to control | 3059 | * cgroup_apply_control_disable - kill or hide csses according to control |
3017 | * @cgrp: parent of the target cgroups | 3060 | * @cgrp: parent of the target cgroups |
3018 | * | 3061 | * |
@@ -3157,36 +3200,10 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, | |||
3157 | cgrp->subtree_control = new_sc; | 3200 | cgrp->subtree_control = new_sc; |
3158 | cgrp->subtree_ss_mask = new_ss; | 3201 | cgrp->subtree_ss_mask = new_ss; |
3159 | 3202 | ||
3160 | /* | 3203 | /* prepare csses */ |
3161 | * Create new csses or make the existing ones visible. A css is | 3204 | ret = cgroup_apply_control_enable(cgrp); |
3162 | * created invisible if it's being implicitly enabled through | 3205 | if (ret) |
3163 | * dependency. An invisible css is made visible when the userland | 3206 | goto err_undo_css; |
3164 | * explicitly enables it. | ||
3165 | */ | ||
3166 | do_each_subsys_mask(ss, ssid, enable) { | ||
3167 | cgroup_for_each_live_child(child, cgrp) { | ||
3168 | if (css_enable & (1 << ssid)) { | ||
3169 | struct cgroup_subsys_state *css; | ||
3170 | |||
3171 | css = css_create(child, ss); | ||
3172 | if (IS_ERR(css)) { | ||
3173 | ret = PTR_ERR(css); | ||
3174 | goto err_undo_css; | ||
3175 | } | ||
3176 | |||
3177 | if (cgrp->subtree_control & (1 << ssid)) { | ||
3178 | ret = css_populate_dir(css, NULL); | ||
3179 | if (ret) | ||
3180 | goto err_undo_css; | ||
3181 | } | ||
3182 | } else { | ||
3183 | ret = css_populate_dir(cgroup_css(child, ss), | ||
3184 | NULL); | ||
3185 | if (ret) | ||
3186 | goto err_undo_css; | ||
3187 | } | ||
3188 | } | ||
3189 | } while_each_subsys_mask(); | ||
3190 | 3207 | ||
3191 | /* | 3208 | /* |
3192 | * At this point, cgroup_e_css() results reflect the new csses | 3209 | * At this point, cgroup_e_css() results reflect the new csses |