Commit 6f3d828f authored by Tejun Heo's avatar Tejun Heo

cgroup: remove cgroup->count and use

cgroup->count tracks the number of css_sets associated with the cgroup
and used only to verify that no css_set is associated when the cgroup
is being destroyed.  It's superflous as the destruction path can
simply check whether cgroup->cset_links is empty instead.

Drop cgroup->count and check ->cset_links directly from
cgroup_destroy_locked().
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarLi Zefan <lizefan@huawei.com>
parent ddd69148
...@@ -169,12 +169,6 @@ struct cgroup_name { ...@@ -169,12 +169,6 @@ struct cgroup_name {
struct cgroup { struct cgroup {
unsigned long flags; /* "unsigned long" so bitops work */ unsigned long flags; /* "unsigned long" so bitops work */
/*
* count users of this cgroup. >0 means busy, but doesn't
* necessarily indicate the number of tasks in the cgroup
*/
atomic_t count;
int id; /* ida allocated in-hierarchy ID */ int id; /* ida allocated in-hierarchy ID */
/* /*
......
...@@ -408,8 +408,7 @@ static void __put_css_set(struct css_set *cset, int taskexit) ...@@ -408,8 +408,7 @@ static void __put_css_set(struct css_set *cset, int taskexit)
list_del(&link->cgrp_link); list_del(&link->cgrp_link);
/* @cgrp can't go away while we're holding css_set_lock */ /* @cgrp can't go away while we're holding css_set_lock */
if (atomic_dec_and_test(&cgrp->count) && if (list_empty(&cgrp->cset_links) && notify_on_release(cgrp)) {
notify_on_release(cgrp)) {
if (taskexit) if (taskexit)
set_bit(CGRP_RELEASABLE, &cgrp->flags); set_bit(CGRP_RELEASABLE, &cgrp->flags);
check_for_release(cgrp); check_for_release(cgrp);
...@@ -616,7 +615,6 @@ static void link_css_set(struct list_head *tmp_links, struct css_set *cset, ...@@ -616,7 +615,6 @@ static void link_css_set(struct list_head *tmp_links, struct css_set *cset,
link = list_first_entry(tmp_links, struct cgrp_cset_link, cset_link); link = list_first_entry(tmp_links, struct cgrp_cset_link, cset_link);
link->cset = cset; link->cset = cset;
link->cgrp = cgrp; link->cgrp = cgrp;
atomic_inc(&cgrp->count);
list_move(&link->cset_link, &cgrp->cset_links); list_move(&link->cset_link, &cgrp->cset_links);
/* /*
* Always add links to the tail of the list so that the list * Always add links to the tail of the list so that the list
...@@ -4370,11 +4368,11 @@ static int cgroup_destroy_locked(struct cgroup *cgrp) ...@@ -4370,11 +4368,11 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
lockdep_assert_held(&cgroup_mutex); lockdep_assert_held(&cgroup_mutex);
/* /*
* css_set_lock prevents @cgrp from being removed while * css_set_lock synchronizes access to ->cset_links and prevents
* __put_css_set() is in progress. * @cgrp from being removed while __put_css_set() is in progress.
*/ */
read_lock(&css_set_lock); read_lock(&css_set_lock);
empty = !atomic_read(&cgrp->count) && list_empty(&cgrp->children); empty = list_empty(&cgrp->cset_links) && list_empty(&cgrp->children);
read_unlock(&css_set_lock); read_unlock(&css_set_lock);
if (!empty) if (!empty)
return -EBUSY; return -EBUSY;
...@@ -5054,7 +5052,7 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks) ...@@ -5054,7 +5052,7 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks)
static void check_for_release(struct cgroup *cgrp) static void check_for_release(struct cgroup *cgrp)
{ {
if (cgroup_is_releasable(cgrp) && if (cgroup_is_releasable(cgrp) &&
!atomic_read(&cgrp->count) && list_empty(&cgrp->children)) { list_empty(&cgrp->cset_links) && list_empty(&cgrp->children)) {
/* /*
* Control Group is currently removeable. If it's not * Control Group is currently removeable. If it's not
* already queued for a userspace notification, queue * already queued for a userspace notification, queue
...@@ -5422,11 +5420,6 @@ static void debug_css_free(struct cgroup *cont) ...@@ -5422,11 +5420,6 @@ static void debug_css_free(struct cgroup *cont)
kfree(cont->subsys[debug_subsys_id]); kfree(cont->subsys[debug_subsys_id]);
} }
static u64 cgroup_refcount_read(struct cgroup *cont, struct cftype *cft)
{
return atomic_read(&cont->count);
}
static u64 debug_taskcount_read(struct cgroup *cont, struct cftype *cft) static u64 debug_taskcount_read(struct cgroup *cont, struct cftype *cft)
{ {
return cgroup_task_count(cont); return cgroup_task_count(cont);
...@@ -5507,10 +5500,6 @@ static u64 releasable_read(struct cgroup *cgrp, struct cftype *cft) ...@@ -5507,10 +5500,6 @@ static u64 releasable_read(struct cgroup *cgrp, struct cftype *cft)
} }
static struct cftype debug_files[] = { static struct cftype debug_files[] = {
{
.name = "cgroup_refcount",
.read_u64 = cgroup_refcount_read,
},
{ {
.name = "taskcount", .name = "taskcount",
.read_u64 = debug_taskcount_read, .read_u64 = debug_taskcount_read,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment