diff options
| author | Tejun Heo <tj@kernel.org> | 2013-06-13 00:04:55 -0400 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2013-06-13 13:55:18 -0400 |
| commit | 6f3d828f0fb7fdaffc6f32cb8a1cb7fcf8824598 (patch) | |
| tree | 662fa290a077ebe5113c877040cb4b891b72d311 | |
| parent | ddd69148bdc45e5e3e55bfde3571daecd5a96d75 (diff) | |
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: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
| -rw-r--r-- | include/linux/cgroup.h | 6 | ||||
| -rw-r--r-- | kernel/cgroup.c | 21 |
2 files changed, 5 insertions, 22 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index c86a93abe83d..81bfd0268e93 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
| @@ -169,12 +169,6 @@ struct cgroup_name { | |||
| 169 | struct cgroup { | 169 | struct cgroup { |
| 170 | unsigned long flags; /* "unsigned long" so bitops work */ | 170 | unsigned long flags; /* "unsigned long" so bitops work */ |
| 171 | 171 | ||
| 172 | /* | ||
| 173 | * count users of this cgroup. >0 means busy, but doesn't | ||
| 174 | * necessarily indicate the number of tasks in the cgroup | ||
| 175 | */ | ||
| 176 | atomic_t count; | ||
| 177 | |||
| 178 | int id; /* ida allocated in-hierarchy ID */ | 172 | int id; /* ida allocated in-hierarchy ID */ |
| 179 | 173 | ||
| 180 | /* | 174 | /* |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 1a68241ca835..49bfd7b0bbda 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -408,8 +408,7 @@ static void __put_css_set(struct css_set *cset, int taskexit) | |||
| 408 | list_del(&link->cgrp_link); | 408 | list_del(&link->cgrp_link); |
| 409 | 409 | ||
| 410 | /* @cgrp can't go away while we're holding css_set_lock */ | 410 | /* @cgrp can't go away while we're holding css_set_lock */ |
| 411 | if (atomic_dec_and_test(&cgrp->count) && | 411 | if (list_empty(&cgrp->cset_links) && notify_on_release(cgrp)) { |
| 412 | notify_on_release(cgrp)) { | ||
| 413 | if (taskexit) | 412 | if (taskexit) |
| 414 | set_bit(CGRP_RELEASABLE, &cgrp->flags); | 413 | set_bit(CGRP_RELEASABLE, &cgrp->flags); |
| 415 | check_for_release(cgrp); | 414 | check_for_release(cgrp); |
| @@ -616,7 +615,6 @@ static void link_css_set(struct list_head *tmp_links, struct css_set *cset, | |||
| 616 | link = list_first_entry(tmp_links, struct cgrp_cset_link, cset_link); | 615 | link = list_first_entry(tmp_links, struct cgrp_cset_link, cset_link); |
| 617 | link->cset = cset; | 616 | link->cset = cset; |
| 618 | link->cgrp = cgrp; | 617 | link->cgrp = cgrp; |
| 619 | atomic_inc(&cgrp->count); | ||
| 620 | list_move(&link->cset_link, &cgrp->cset_links); | 618 | list_move(&link->cset_link, &cgrp->cset_links); |
| 621 | /* | 619 | /* |
| 622 | * Always add links to the tail of the list so that the list | 620 | * 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 | lockdep_assert_held(&cgroup_mutex); | 4368 | lockdep_assert_held(&cgroup_mutex); |
| 4371 | 4369 | ||
| 4372 | /* | 4370 | /* |
| 4373 | * css_set_lock prevents @cgrp from being removed while | 4371 | * css_set_lock synchronizes access to ->cset_links and prevents |
| 4374 | * __put_css_set() is in progress. | 4372 | * @cgrp from being removed while __put_css_set() is in progress. |
| 4375 | */ | 4373 | */ |
| 4376 | read_lock(&css_set_lock); | 4374 | read_lock(&css_set_lock); |
| 4377 | empty = !atomic_read(&cgrp->count) && list_empty(&cgrp->children); | 4375 | empty = list_empty(&cgrp->cset_links) && list_empty(&cgrp->children); |
| 4378 | read_unlock(&css_set_lock); | 4376 | read_unlock(&css_set_lock); |
| 4379 | if (!empty) | 4377 | if (!empty) |
| 4380 | return -EBUSY; | 4378 | return -EBUSY; |
| @@ -5054,7 +5052,7 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks) | |||
| 5054 | static void check_for_release(struct cgroup *cgrp) | 5052 | static void check_for_release(struct cgroup *cgrp) |
| 5055 | { | 5053 | { |
| 5056 | if (cgroup_is_releasable(cgrp) && | 5054 | if (cgroup_is_releasable(cgrp) && |
| 5057 | !atomic_read(&cgrp->count) && list_empty(&cgrp->children)) { | 5055 | list_empty(&cgrp->cset_links) && list_empty(&cgrp->children)) { |
| 5058 | /* | 5056 | /* |
| 5059 | * Control Group is currently removeable. If it's not | 5057 | * Control Group is currently removeable. If it's not |
| 5060 | * already queued for a userspace notification, queue | 5058 | * already queued for a userspace notification, queue |
| @@ -5422,11 +5420,6 @@ static void debug_css_free(struct cgroup *cont) | |||
| 5422 | kfree(cont->subsys[debug_subsys_id]); | 5420 | kfree(cont->subsys[debug_subsys_id]); |
| 5423 | } | 5421 | } |
| 5424 | 5422 | ||
| 5425 | static u64 cgroup_refcount_read(struct cgroup *cont, struct cftype *cft) | ||
| 5426 | { | ||
| 5427 | return atomic_read(&cont->count); | ||
| 5428 | } | ||
| 5429 | |||
| 5430 | static u64 debug_taskcount_read(struct cgroup *cont, struct cftype *cft) | 5423 | static u64 debug_taskcount_read(struct cgroup *cont, struct cftype *cft) |
| 5431 | { | 5424 | { |
| 5432 | return cgroup_task_count(cont); | 5425 | return cgroup_task_count(cont); |
| @@ -5508,10 +5501,6 @@ static u64 releasable_read(struct cgroup *cgrp, struct cftype *cft) | |||
| 5508 | 5501 | ||
| 5509 | static struct cftype debug_files[] = { | 5502 | static struct cftype debug_files[] = { |
| 5510 | { | 5503 | { |
| 5511 | .name = "cgroup_refcount", | ||
| 5512 | .read_u64 = cgroup_refcount_read, | ||
| 5513 | }, | ||
| 5514 | { | ||
| 5515 | .name = "taskcount", | 5504 | .name = "taskcount", |
| 5516 | .read_u64 = debug_taskcount_read, | 5505 | .read_u64 = debug_taskcount_read, |
| 5517 | }, | 5506 | }, |
