aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-05-16 13:22:52 -0400
committerTejun Heo <tj@kernel.org>2014-05-16 13:22:52 -0400
commitf3d4650015301d1c880df4523f7e7ef320a38aab (patch)
treeed6040e2019347e8bf9525c15db859737ecae709
parent184faf32328c65c9d86b19577b8d8b90bdd2cd2e (diff)
cgroup: convert cgroup_has_live_children() into css_has_online_children()
Now that cgroup liveliness and css onliness are the same state, convert cgroup_has_live_children() into css_has_online_children() so that it can be used for actual csses too. The function now uses css_for_each_child() for iteration and is published. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
-rw-r--r--include/linux/cgroup.h2
-rw-r--r--kernel/cgroup.c32
2 files changed, 22 insertions, 12 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 51a339c99eb6..b76999954beb 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -873,6 +873,8 @@ css_next_descendant_post(struct cgroup_subsys_state *pos,
873 for ((pos) = css_next_descendant_post(NULL, (css)); (pos); \ 873 for ((pos) = css_next_descendant_post(NULL, (css)); (pos); \
874 (pos) = css_next_descendant_post((pos), (css))) 874 (pos) = css_next_descendant_post((pos), (css)))
875 875
876bool css_has_online_children(struct cgroup_subsys_state *css);
877
876/* A css_task_iter should be treated as an opaque object */ 878/* A css_task_iter should be treated as an opaque object */
877struct css_task_iter { 879struct css_task_iter {
878 struct cgroup_subsys *ss; 880 struct cgroup_subsys *ss;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 004004fd0ded..082bb842b11a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -175,7 +175,6 @@ static int need_forkexit_callback __read_mostly;
175static struct cftype cgroup_base_files[]; 175static struct cftype cgroup_base_files[];
176 176
177static void cgroup_put(struct cgroup *cgrp); 177static void cgroup_put(struct cgroup *cgrp);
178static bool cgroup_has_live_children(struct cgroup *cgrp);
179static int rebind_subsystems(struct cgroup_root *dst_root, 178static int rebind_subsystems(struct cgroup_root *dst_root,
180 unsigned int ss_mask); 179 unsigned int ss_mask);
181static int cgroup_destroy_locked(struct cgroup *cgrp); 180static int cgroup_destroy_locked(struct cgroup *cgrp);
@@ -1769,7 +1768,7 @@ static void cgroup_kill_sb(struct super_block *sb)
1769 * This prevents new mounts by disabling percpu_ref_tryget_live(). 1768 * This prevents new mounts by disabling percpu_ref_tryget_live().
1770 * cgroup_mount() may wait for @root's release. 1769 * cgroup_mount() may wait for @root's release.
1771 */ 1770 */
1772 if (cgroup_has_live_children(&root->cgrp)) 1771 if (css_has_online_children(&root->cgrp.self))
1773 cgroup_put(&root->cgrp); 1772 cgroup_put(&root->cgrp);
1774 else 1773 else
1775 percpu_ref_kill(&root->cgrp.self.refcnt); 1774 percpu_ref_kill(&root->cgrp.self.refcnt);
@@ -3291,19 +3290,28 @@ css_next_descendant_post(struct cgroup_subsys_state *pos,
3291 return pos->parent; 3290 return pos->parent;
3292} 3291}
3293 3292
3294static bool cgroup_has_live_children(struct cgroup *cgrp) 3293/**
3294 * css_has_online_children - does a css have online children
3295 * @css: the target css
3296 *
3297 * Returns %true if @css has any online children; otherwise, %false. This
3298 * function can be called from any context but the caller is responsible
3299 * for synchronizing against on/offlining as necessary.
3300 */
3301bool css_has_online_children(struct cgroup_subsys_state *css)
3295{ 3302{
3296 struct cgroup *child; 3303 struct cgroup_subsys_state *child;
3304 bool ret = false;
3297 3305
3298 rcu_read_lock(); 3306 rcu_read_lock();
3299 list_for_each_entry_rcu(child, &cgrp->self.children, self.sibling) { 3307 css_for_each_child(child, css) {
3300 if (!cgroup_is_dead(child)) { 3308 if (css->flags & CSS_ONLINE) {
3301 rcu_read_unlock(); 3309 ret = true;
3302 return true; 3310 break;
3303 } 3311 }
3304 } 3312 }
3305 rcu_read_unlock(); 3313 rcu_read_unlock();
3306 return false; 3314 return ret;
3307} 3315}
3308 3316
3309/** 3317/**
@@ -4535,7 +4543,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4535 * ->self.children as dead children linger on it while being 4543 * ->self.children as dead children linger on it while being
4536 * drained; otherwise, "rmdir parent/child parent" may fail. 4544 * drained; otherwise, "rmdir parent/child parent" may fail.
4537 */ 4545 */
4538 if (cgroup_has_live_children(cgrp)) 4546 if (css_has_online_children(&cgrp->self))
4539 return -EBUSY; 4547 return -EBUSY;
4540 4548
4541 /* 4549 /*
@@ -5014,8 +5022,8 @@ void cgroup_exit(struct task_struct *tsk)
5014 5022
5015static void check_for_release(struct cgroup *cgrp) 5023static void check_for_release(struct cgroup *cgrp)
5016{ 5024{
5017 if (cgroup_is_releasable(cgrp) && 5025 if (cgroup_is_releasable(cgrp) && list_empty(&cgrp->cset_links) &&
5018 list_empty(&cgrp->cset_links) && !cgroup_has_live_children(cgrp)) { 5026 !css_has_online_children(&cgrp->self)) {
5019 /* 5027 /*
5020 * Control Group is currently removeable. If it's not 5028 * Control Group is currently removeable. If it's not
5021 * already queued for a userspace notification, queue 5029 * already queued for a userspace notification, queue