mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-26 09:10:51 +07:00
cgroup: factor out cgroup_apply_control_disable() from cgroup_subtree_control_write()
Factor out css disabling and hiding into cgroup_apply_control_disable(). * 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 and @css_disable, simply disable or hide csses according to the current cgroup_control() and cgroup_ss_mask(). This leads to the same result and is simpler and more robust. * This allows error handling path to share the same code. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Zefan Li <lizefan@huawei.com>
This commit is contained in:
parent
1b9b96a12b
commit
12b3bb6af8
@ -3012,6 +3012,43 @@ static bool cgroup_drain_offline(struct cgroup *cgrp)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* cgroup_apply_control_disable - kill or hide csses according to control
|
||||
* @cgrp: parent of the target cgroups
|
||||
*
|
||||
* Walk @cgrp's children and kill and hide csses so that they match
|
||||
* cgroup_ss_mask() and cgroup_visible_mask().
|
||||
*
|
||||
* A css is hidden when the userland requests it to be disabled while other
|
||||
* subsystems are still depending on it. The css must not actively control
|
||||
* resources and be in the vanilla state if it's made visible again later.
|
||||
* Controllers which may be depended upon should provide ->css_reset() for
|
||||
* this purpose.
|
||||
*/
|
||||
static void cgroup_apply_control_disable(struct cgroup *cgrp)
|
||||
{
|
||||
struct cgroup *dsct;
|
||||
struct cgroup_subsys *ss;
|
||||
int ssid;
|
||||
|
||||
cgroup_for_each_live_child(dsct, cgrp) {
|
||||
for_each_subsys(ss, ssid) {
|
||||
struct cgroup_subsys_state *css = cgroup_css(dsct, ss);
|
||||
|
||||
if (!css)
|
||||
continue;
|
||||
|
||||
if (!(cgroup_ss_mask(dsct) & (1 << ss->id))) {
|
||||
kill_css(css);
|
||||
} else if (!(cgroup_control(dsct) & (1 << ss->id))) {
|
||||
css_clear_dir(css, NULL);
|
||||
if (ss->css_reset)
|
||||
ss->css_reset(css);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* change the enabled child controllers for a cgroup in the default hierarchy */
|
||||
static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
|
||||
char *buf, size_t nbytes,
|
||||
@ -3160,27 +3197,8 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
|
||||
if (ret)
|
||||
goto err_undo_css;
|
||||
|
||||
/*
|
||||
* All tasks are migrated out of disabled csses. Kill or hide
|
||||
* them. A css is hidden when the userland requests it to be
|
||||
* disabled while other subsystems are still depending on it. The
|
||||
* css must not actively control resources and be in the vanilla
|
||||
* state if it's made visible again later. Controllers which may
|
||||
* be depended upon should provide ->css_reset() for this purpose.
|
||||
*/
|
||||
do_each_subsys_mask(ss, ssid, disable) {
|
||||
cgroup_for_each_live_child(child, cgrp) {
|
||||
struct cgroup_subsys_state *css = cgroup_css(child, ss);
|
||||
|
||||
if (css_disable & (1 << ssid)) {
|
||||
kill_css(css);
|
||||
} else {
|
||||
css_clear_dir(css, NULL);
|
||||
if (ss->css_reset)
|
||||
ss->css_reset(css);
|
||||
}
|
||||
}
|
||||
} while_each_subsys_mask();
|
||||
/* all tasks are migrated out of disabled csses, commit disable */
|
||||
cgroup_apply_control_disable(cgrp);
|
||||
|
||||
kernfs_activate(cgrp->kn);
|
||||
ret = 0;
|
||||
@ -3189,22 +3207,12 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
|
||||
return ret ?: nbytes;
|
||||
|
||||
err_undo_css:
|
||||
/* restore masks and shoot down new csses */
|
||||
cgrp->subtree_control = old_sc;
|
||||
cgrp->subtree_ss_mask = old_ss;
|
||||
|
||||
do_each_subsys_mask(ss, ssid, enable) {
|
||||
cgroup_for_each_live_child(child, cgrp) {
|
||||
struct cgroup_subsys_state *css = cgroup_css(child, ss);
|
||||
cgroup_apply_control_disable(cgrp);
|
||||
|
||||
if (!css)
|
||||
continue;
|
||||
|
||||
if (css_enable & (1 << ssid))
|
||||
kill_css(css);
|
||||
else
|
||||
css_clear_dir(css, NULL);
|
||||
}
|
||||
} while_each_subsys_mask();
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user