aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorZefan Li <lizefan@huawei.com>2014-09-19 04:51:00 -0400
committerTejun Heo <tj@kernel.org>2014-09-19 09:29:32 -0400
commita25eb52e81a40e986179a790fbb5a1f02f482b7a (patch)
tree1d88c2bfdd17f168a5c21b4038d697148187d958 /kernel/cgroup.c
parent4e2ba65068ac1d0e8c9df78a4ad787cf39640418 (diff)
cgroup: remove CGRP_RELEASABLE flag
We call put_css_set() after setting CGRP_RELEASABLE flag in cgroup_task_migrate(), but in other places we call it without setting the flag. I don't see the necessity of this flag. Moreover once the flag is set, it will never be cleared, unless writing to the notify_on_release control file, so it can be quite confusing if we look at the output of debug.releasable. # mount -t cgroup -o debug xxx /cgroup # mkdir /cgroup/child # cat /cgroup/child/debug.releasable 0 <-- shows 0 though the cgroup is empty # echo $$ > /cgroup/child/tasks # cat /cgroup/child/debug.releasable 0 # echo $$ > /cgroup/tasks && echo $$ > /cgroup/child/tasks # cat /proc/child/debug.releasable 1 <-- shows 1 though the cgroup is not empty This patch removes the flag, and now debug.releasable shows if the cgroup is empty or not. Signed-off-by: Zefan Li <lizefan@huawei.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c40
1 files changed, 13 insertions, 27 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index df7733b48d2e..16e3a4f5c9dc 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -329,14 +329,6 @@ bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor)
329 return false; 329 return false;
330} 330}
331 331
332static int cgroup_is_releasable(const struct cgroup *cgrp)
333{
334 const int bits =
335 (1 << CGRP_RELEASABLE) |
336 (1 << CGRP_NOTIFY_ON_RELEASE);
337 return (cgrp->flags & bits) == bits;
338}
339
340static int notify_on_release(const struct cgroup *cgrp) 332static int notify_on_release(const struct cgroup *cgrp)
341{ 333{
342 return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); 334 return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
@@ -491,7 +483,7 @@ static unsigned long css_set_hash(struct cgroup_subsys_state *css[])
491 return key; 483 return key;
492} 484}
493 485
494static void put_css_set_locked(struct css_set *cset, bool taskexit) 486static void put_css_set_locked(struct css_set *cset)
495{ 487{
496 struct cgrp_cset_link *link, *tmp_link; 488 struct cgrp_cset_link *link, *tmp_link;
497 struct cgroup_subsys *ss; 489 struct cgroup_subsys *ss;
@@ -517,11 +509,7 @@ static void put_css_set_locked(struct css_set *cset, bool taskexit)
517 /* @cgrp can't go away while we're holding css_set_rwsem */ 509 /* @cgrp can't go away while we're holding css_set_rwsem */
518 if (list_empty(&cgrp->cset_links)) { 510 if (list_empty(&cgrp->cset_links)) {
519 cgroup_update_populated(cgrp, false); 511 cgroup_update_populated(cgrp, false);
520 if (notify_on_release(cgrp)) { 512 check_for_release(cgrp);
521 if (taskexit)
522 set_bit(CGRP_RELEASABLE, &cgrp->flags);
523 check_for_release(cgrp);
524 }
525 } 513 }
526 514
527 kfree(link); 515 kfree(link);
@@ -530,7 +518,7 @@ static void put_css_set_locked(struct css_set *cset, bool taskexit)
530 kfree_rcu(cset, rcu_head); 518 kfree_rcu(cset, rcu_head);
531} 519}
532 520
533static void put_css_set(struct css_set *cset, bool taskexit) 521static void put_css_set(struct css_set *cset)
534{ 522{
535 /* 523 /*
536 * Ensure that the refcount doesn't hit zero while any readers 524 * Ensure that the refcount doesn't hit zero while any readers
@@ -541,7 +529,7 @@ static void put_css_set(struct css_set *cset, bool taskexit)
541 return; 529 return;
542 530
543 down_write(&css_set_rwsem); 531 down_write(&css_set_rwsem);
544 put_css_set_locked(cset, taskexit); 532 put_css_set_locked(cset);
545 up_write(&css_set_rwsem); 533 up_write(&css_set_rwsem);
546} 534}
547 535
@@ -2037,8 +2025,7 @@ static void cgroup_task_migrate(struct cgroup *old_cgrp,
2037 * task. As trading it for new_cset is protected by cgroup_mutex, 2025 * task. As trading it for new_cset is protected by cgroup_mutex,
2038 * we're safe to drop it here; it will be freed under RCU. 2026 * we're safe to drop it here; it will be freed under RCU.
2039 */ 2027 */
2040 set_bit(CGRP_RELEASABLE, &old_cgrp->flags); 2028 put_css_set_locked(old_cset);
2041 put_css_set_locked(old_cset, false);
2042} 2029}
2043 2030
2044/** 2031/**
@@ -2059,7 +2046,7 @@ static void cgroup_migrate_finish(struct list_head *preloaded_csets)
2059 cset->mg_src_cgrp = NULL; 2046 cset->mg_src_cgrp = NULL;
2060 cset->mg_dst_cset = NULL; 2047 cset->mg_dst_cset = NULL;
2061 list_del_init(&cset->mg_preload_node); 2048 list_del_init(&cset->mg_preload_node);
2062 put_css_set_locked(cset, false); 2049 put_css_set_locked(cset);
2063 } 2050 }
2064 up_write(&css_set_rwsem); 2051 up_write(&css_set_rwsem);
2065} 2052}
@@ -2153,8 +2140,8 @@ static int cgroup_migrate_prepare_dst(struct cgroup *dst_cgrp,
2153 if (src_cset == dst_cset) { 2140 if (src_cset == dst_cset) {
2154 src_cset->mg_src_cgrp = NULL; 2141 src_cset->mg_src_cgrp = NULL;
2155 list_del_init(&src_cset->mg_preload_node); 2142 list_del_init(&src_cset->mg_preload_node);
2156 put_css_set(src_cset, false); 2143 put_css_set(src_cset);
2157 put_css_set(dst_cset, false); 2144 put_css_set(dst_cset);
2158 continue; 2145 continue;
2159 } 2146 }
2160 2147
@@ -2163,7 +2150,7 @@ static int cgroup_migrate_prepare_dst(struct cgroup *dst_cgrp,
2163 if (list_empty(&dst_cset->mg_preload_node)) 2150 if (list_empty(&dst_cset->mg_preload_node))
2164 list_add(&dst_cset->mg_preload_node, &csets); 2151 list_add(&dst_cset->mg_preload_node, &csets);
2165 else 2152 else
2166 put_css_set(dst_cset, false); 2153 put_css_set(dst_cset);
2167 } 2154 }
2168 2155
2169 list_splice_tail(&csets, preloaded_csets); 2156 list_splice_tail(&csets, preloaded_csets);
@@ -4159,7 +4146,6 @@ static u64 cgroup_read_notify_on_release(struct cgroup_subsys_state *css,
4159static int cgroup_write_notify_on_release(struct cgroup_subsys_state *css, 4146static int cgroup_write_notify_on_release(struct cgroup_subsys_state *css,
4160 struct cftype *cft, u64 val) 4147 struct cftype *cft, u64 val)
4161{ 4148{
4162 clear_bit(CGRP_RELEASABLE, &css->cgroup->flags);
4163 if (val) 4149 if (val)
4164 set_bit(CGRP_NOTIFY_ON_RELEASE, &css->cgroup->flags); 4150 set_bit(CGRP_NOTIFY_ON_RELEASE, &css->cgroup->flags);
4165 else 4151 else
@@ -4806,7 +4792,6 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4806 */ 4792 */
4807 kernfs_remove(cgrp->kn); 4793 kernfs_remove(cgrp->kn);
4808 4794
4809 set_bit(CGRP_RELEASABLE, &cgroup_parent(cgrp)->flags);
4810 check_for_release(cgroup_parent(cgrp)); 4795 check_for_release(cgroup_parent(cgrp));
4811 4796
4812 /* put the base reference */ 4797 /* put the base reference */
@@ -5244,12 +5229,12 @@ void cgroup_exit(struct task_struct *tsk)
5244 } 5229 }
5245 5230
5246 if (put_cset) 5231 if (put_cset)
5247 put_css_set(cset, true); 5232 put_css_set(cset);
5248} 5233}
5249 5234
5250static void check_for_release(struct cgroup *cgrp) 5235static void check_for_release(struct cgroup *cgrp)
5251{ 5236{
5252 if (cgroup_is_releasable(cgrp) && !cgroup_has_tasks(cgrp) && 5237 if (notify_on_release(cgrp) && !cgroup_has_tasks(cgrp) &&
5253 !css_has_online_children(&cgrp->self) && !cgroup_is_dead(cgrp)) 5238 !css_has_online_children(&cgrp->self) && !cgroup_is_dead(cgrp))
5254 schedule_work(&cgrp->release_agent_work); 5239 schedule_work(&cgrp->release_agent_work);
5255} 5240}
@@ -5496,7 +5481,8 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v)
5496 5481
5497static u64 releasable_read(struct cgroup_subsys_state *css, struct cftype *cft) 5482static u64 releasable_read(struct cgroup_subsys_state *css, struct cftype *cft)
5498{ 5483{
5499 return test_bit(CGRP_RELEASABLE, &css->cgroup->flags); 5484 return (!cgroup_has_tasks(css->cgroup) &&
5485 !css_has_online_children(&css->cgroup->self));
5500} 5486}
5501 5487
5502static struct cftype debug_files[] = { 5488static struct cftype debug_files[] = {