diff options
author | Tejun Heo <tj@kernel.org> | 2015-10-15 16:41:51 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2015-10-15 16:41:51 -0400 |
commit | 91486f61f486662c27ef86dd910f875832e3a5de (patch) | |
tree | 19c2bbe7e0bfd8115147d883b47b4978e090048b | |
parent | 2ceb231b0ab0e3d700c5f7c839273bfeecbefe3b (diff) |
cgroup: make cgroup_destroy_locked() test cgroup_is_populated()
cgroup_destroy_locked() currently tests whether any css_sets are
associated to reject removal if the cgroup contains tasks. This works
because a css_set's refcnt converges with the number of tasks linked
to it and thus there's no css_set linked to a cgroup if it doesn't
have any live tasks.
To help tracking resource usage of zombie tasks, putting the ref of
css_set will be separated from disassociating the task from the
css_set which means that a cgroup may have css_sets linked to it even
when it doesn't have any live tasks.
This patch updates cgroup_destroy_locked() so that it tests
cgroup_is_populated(), which counts the number of populated css_sets,
instead of whether cgrp->cset_links is empty to determine whether the
cgroup is populated or not. This ensures that rmdirs won't be
incorrectly rejected for cgroups which only contain zombie tasks.
Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r-- | kernel/cgroup.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index ea87340af871..61ee85ded6ae 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -4998,16 +4998,15 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) | |||
4998 | __releases(&cgroup_mutex) __acquires(&cgroup_mutex) | 4998 | __releases(&cgroup_mutex) __acquires(&cgroup_mutex) |
4999 | { | 4999 | { |
5000 | struct cgroup_subsys_state *css; | 5000 | struct cgroup_subsys_state *css; |
5001 | bool empty; | ||
5002 | int ssid; | 5001 | int ssid; |
5003 | 5002 | ||
5004 | lockdep_assert_held(&cgroup_mutex); | 5003 | lockdep_assert_held(&cgroup_mutex); |
5005 | 5004 | ||
5006 | /* css_set_rwsem synchronizes access to ->cset_links */ | 5005 | /* |
5007 | down_read(&css_set_rwsem); | 5006 | * Only migration can raise populated from zero and we're already |
5008 | empty = list_empty(&cgrp->cset_links); | 5007 | * holding cgroup_mutex. |
5009 | up_read(&css_set_rwsem); | 5008 | */ |
5010 | if (!empty) | 5009 | if (cgroup_is_populated(cgrp)) |
5011 | return -EBUSY; | 5010 | return -EBUSY; |
5012 | 5011 | ||
5013 | /* | 5012 | /* |