mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +00:00
cgroup/freezer: Reduce redundant traversal for cgroup_freeze
Whether a cgroup is frozen is determined solely by whether it is set to to be frozen and whether its parent is frozen. Currently, when is cgroup is frozen or unfrozen, it iterates through the entire subtree to freeze or unfreeze its descentdants. However, this is unesessary for a cgroup that does not change its effective frozen status. This path aims to skip the subtree if its parent does not have a change in effective freeze. For an example, subtree like, a-b-c-d-e-f-g, when a is frozen, the entire tree is frozen. If we freeze b and c again, it is unesessary to iterate d, e, f and g. So does that If we unfreeze b/c. Reviewed-by: Michal Koutný <mkoutny@suse.com> Signed-off-by: Chen Ridong <chenridong@huawei.com> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
2190df6c91
commit
ee1251fc0c
@ -398,7 +398,7 @@ struct cgroup_freezer_state {
|
||||
bool freeze;
|
||||
|
||||
/* Should the cgroup actually be frozen? */
|
||||
int e_freeze;
|
||||
bool e_freeze;
|
||||
|
||||
/* Fields below are protected by css_set_lock */
|
||||
|
||||
|
@ -260,8 +260,10 @@ void cgroup_freezer_migrate_task(struct task_struct *task,
|
||||
void cgroup_freeze(struct cgroup *cgrp, bool freeze)
|
||||
{
|
||||
struct cgroup_subsys_state *css;
|
||||
struct cgroup *parent;
|
||||
struct cgroup *dsct;
|
||||
bool applied = false;
|
||||
bool old_e;
|
||||
|
||||
lockdep_assert_held(&cgroup_mutex);
|
||||
|
||||
@ -282,22 +284,18 @@ void cgroup_freeze(struct cgroup *cgrp, bool freeze)
|
||||
if (cgroup_is_dead(dsct))
|
||||
continue;
|
||||
|
||||
if (freeze) {
|
||||
dsct->freezer.e_freeze++;
|
||||
/*
|
||||
* Already frozen because of ancestor's settings?
|
||||
*/
|
||||
if (dsct->freezer.e_freeze > 1)
|
||||
continue;
|
||||
} else {
|
||||
dsct->freezer.e_freeze--;
|
||||
/*
|
||||
* Still frozen because of ancestor's settings?
|
||||
*/
|
||||
if (dsct->freezer.e_freeze > 0)
|
||||
continue;
|
||||
|
||||
WARN_ON_ONCE(dsct->freezer.e_freeze < 0);
|
||||
/*
|
||||
* e_freeze is affected by parent's e_freeze and dst's freeze.
|
||||
* If old e_freeze eq new e_freeze, no change, its children
|
||||
* will not be affected. So do nothing and skip the subtree
|
||||
*/
|
||||
old_e = dsct->freezer.e_freeze;
|
||||
parent = cgroup_parent(dsct);
|
||||
dsct->freezer.e_freeze = (dsct->freezer.freeze ||
|
||||
parent->freezer.e_freeze);
|
||||
if (dsct->freezer.e_freeze == old_e) {
|
||||
css = css_rightmost_descendant(css);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user