aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2016-03-03 09:57:59 -0500
committerTejun Heo <tj@kernel.org>2016-03-03 09:57:59 -0500
commitbdb53bd797dcef46d1a252b9529f8fd511bf714c (patch)
tree28d344a6ebeecc252596933257412a92f3ab1626
parent12b3bb6af862477f96e1adac51b201a143a8f3c4 (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.c77
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 */
3028static 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