aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-02-13 06:58:39 -0500
committerTejun Heo <tj@kernel.org>2014-02-13 06:58:39 -0500
commit07bc356ed2950048d33d667e933e1b913c6e6b6d (patch)
tree5efb91f14c21157285965cfcbf480a3538dda35e
parentafeb0f9fd425239aa477c842480f240bfb6325b3 (diff)
cgroup: implement cgroup_has_tasks() and unexport cgroup_task_count()
cgroup_task_count() read-locks css_set_lock and walks all tasks to count them and then returns the result. The only thing all the users want is determining whether the cgroup is empty or not. This patch implements cgroup_has_tasks() which tests whether cgroup->cset_links is empty, replaces all cgroup_task_count() usages and unexports it. Note that the test isn't synchronized. This is the same as before. The test has always been racy. This will help planned css_set locking update. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com> Acked-by: Michal Hocko <mhocko@suse.cz> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Balbir Singh <bsingharora@gmail.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
-rw-r--r--include/linux/cgroup.h8
-rw-r--r--kernel/cgroup.c2
-rw-r--r--kernel/cpuset.c2
-rw-r--r--mm/memcontrol.c4
4 files changed, 10 insertions, 6 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index e2ffcdc26cb7..72154fb44fb5 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -457,6 +457,12 @@ static inline bool cgroup_sane_behavior(const struct cgroup *cgrp)
457 return cgrp->root->flags & CGRP_ROOT_SANE_BEHAVIOR; 457 return cgrp->root->flags & CGRP_ROOT_SANE_BEHAVIOR;
458} 458}
459 459
460/* no synchronization, the result can only be used as a hint */
461static inline bool cgroup_has_tasks(struct cgroup *cgrp)
462{
463 return !list_empty(&cgrp->cset_links);
464}
465
460/* returns ino associated with a cgroup, 0 indicates unmounted root */ 466/* returns ino associated with a cgroup, 0 indicates unmounted root */
461static inline ino_t cgroup_ino(struct cgroup *cgrp) 467static inline ino_t cgroup_ino(struct cgroup *cgrp)
462{ 468{
@@ -516,8 +522,6 @@ int cgroup_rm_cftypes(struct cftype *cfts);
516 522
517bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor); 523bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor);
518 524
519int cgroup_task_count(const struct cgroup *cgrp);
520
521/* 525/*
522 * Control Group taskset, used to pass around set of tasks to cgroup_subsys 526 * Control Group taskset, used to pass around set of tasks to cgroup_subsys
523 * methods. 527 * methods.
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 2469699408bd..ec7746e5ded1 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2391,7 +2391,7 @@ EXPORT_SYMBOL_GPL(cgroup_add_cftypes);
2391 * 2391 *
2392 * Return the number of tasks in the cgroup. 2392 * Return the number of tasks in the cgroup.
2393 */ 2393 */
2394int cgroup_task_count(const struct cgroup *cgrp) 2394static int cgroup_task_count(const struct cgroup *cgrp)
2395{ 2395{
2396 int count = 0; 2396 int count = 0;
2397 struct cgrp_cset_link *link; 2397 struct cgrp_cset_link *link;
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index e97a6e88d036..ae190b0a196a 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -467,7 +467,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)
467 * be changed to have empty cpus_allowed or mems_allowed. 467 * be changed to have empty cpus_allowed or mems_allowed.
468 */ 468 */
469 ret = -ENOSPC; 469 ret = -ENOSPC;
470 if ((cgroup_task_count(cur->css.cgroup) || cur->attach_in_progress)) { 470 if ((cgroup_has_tasks(cur->css.cgroup) || cur->attach_in_progress)) {
471 if (!cpumask_empty(cur->cpus_allowed) && 471 if (!cpumask_empty(cur->cpus_allowed) &&
472 cpumask_empty(trial->cpus_allowed)) 472 cpumask_empty(trial->cpus_allowed))
473 goto out; 473 goto out;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c1c25494f7ae..d9c6ac1532e6 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4958,7 +4958,7 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg)
4958 struct cgroup *cgrp = memcg->css.cgroup; 4958 struct cgroup *cgrp = memcg->css.cgroup;
4959 4959
4960 /* returns EBUSY if there is a task or if we come here twice. */ 4960 /* returns EBUSY if there is a task or if we come here twice. */
4961 if (cgroup_task_count(cgrp) || !list_empty(&cgrp->children)) 4961 if (cgroup_has_tasks(cgrp) || !list_empty(&cgrp->children))
4962 return -EBUSY; 4962 return -EBUSY;
4963 4963
4964 /* we call try-to-free pages for make this cgroup empty */ 4964 /* we call try-to-free pages for make this cgroup empty */
@@ -5140,7 +5140,7 @@ static int __memcg_activate_kmem(struct mem_cgroup *memcg,
5140 * of course permitted. 5140 * of course permitted.
5141 */ 5141 */
5142 mutex_lock(&memcg_create_mutex); 5142 mutex_lock(&memcg_create_mutex);
5143 if (cgroup_task_count(memcg->css.cgroup) || memcg_has_children(memcg)) 5143 if (cgroup_has_tasks(memcg->css.cgroup) || memcg_has_children(memcg))
5144 err = -EBUSY; 5144 err = -EBUSY;
5145 mutex_unlock(&memcg_create_mutex); 5145 mutex_unlock(&memcg_create_mutex);
5146 if (err) 5146 if (err)