aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-08-13 20:22:50 -0400
committerTejun Heo <tj@kernel.org>2013-08-13 20:22:50 -0400
commit09a503ea3a816b285b0b402b7f785eaec0c7a7e1 (patch)
tree67f3a360c2e8e0851825cf3e1675bd5244d15926 /kernel/cgroup.c
parentf20104de55a212a9742d8df1807f1f29dc95b748 (diff)
cgroup: decouple cgroup_subsys_state destruction from cgroup destruction
Currently, css (cgroup_subsys_state) lifetime is tied to that of the associated cgroup. css's are created when the associated cgroup is created and destroyed when it gets destroyed. Also, individual css's aren't RCU protected but the whole cgroup is. With the planned unified hierarchy, css's will need to be dynamically created and destroyed within the lifetime of a cgroup. To enable such usages, this patch decouples css destruction from cgroup destruction - offline_css() invocation and the final css_put() are moved from cgroup_destroy_css_killed() to css_killed_work_fn(). Now each css is individually offlined and put as its reference count is killed instead of waiting for all css's attached to the cgroup to finish refcnt killing and then proceeding to offlining and putting them together. While this changes the order of destruction operations, the changes shouldn't be noticeable to cgroup subsystems or userland. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c52
1 files changed, 24 insertions, 28 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 174f4c3d72ef..3c4c4b01ffe5 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4355,6 +4355,7 @@ static void offline_css(struct cgroup_subsys_state *css)
4355 ss->css_offline(css); 4355 ss->css_offline(css);
4356 4356
4357 css->flags &= ~CSS_ONLINE; 4357 css->flags &= ~CSS_ONLINE;
4358 css->cgroup->nr_css--;
4358} 4359}
4359 4360
4360/* 4361/*
@@ -4559,14 +4560,29 @@ static void css_killed_work_fn(struct work_struct *work)
4559 mutex_lock(&cgroup_mutex); 4560 mutex_lock(&cgroup_mutex);
4560 4561
4561 /* 4562 /*
4563 * css_tryget() is guaranteed to fail now. Tell subsystems to
4564 * initate destruction.
4565 */
4566 offline_css(css);
4567
4568 /*
4562 * If @cgrp is marked dead, it's waiting for refs of all css's to 4569 * If @cgrp is marked dead, it's waiting for refs of all css's to
4563 * be disabled before proceeding to the second phase of cgroup 4570 * be disabled before proceeding to the second phase of cgroup
4564 * destruction. If we are the last one, kick it off. 4571 * destruction. If we are the last one, kick it off.
4565 */ 4572 */
4566 if (!--cgrp->nr_css && cgroup_is_dead(cgrp)) 4573 if (!cgrp->nr_css && cgroup_is_dead(cgrp))
4567 cgroup_destroy_css_killed(cgrp); 4574 cgroup_destroy_css_killed(cgrp);
4568 4575
4569 mutex_unlock(&cgroup_mutex); 4576 mutex_unlock(&cgroup_mutex);
4577
4578 /*
4579 * Put the css refs from kill_css(). Each css holds an extra
4580 * reference to the cgroup's dentry and cgroup removal proceeds
4581 * regardless of css refs. On the last put of each css, whenever
4582 * that may be, the extra dentry ref is put so that dentry
4583 * destruction happens only after all css's are released.
4584 */
4585 css_put(css);
4570} 4586}
4571 4587
4572/* css kill confirmation processing requires process context, bounce */ 4588/* css kill confirmation processing requires process context, bounce */
@@ -4633,11 +4649,10 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4633 * as killed on all CPUs on return. 4649 * as killed on all CPUs on return.
4634 * 4650 *
4635 * Use percpu_ref_kill_and_confirm() to get notifications as each 4651 * Use percpu_ref_kill_and_confirm() to get notifications as each
4636 * css is confirmed to be seen as killed on all CPUs. The 4652 * css is confirmed to be seen as killed on all CPUs.
4637 * notification callback keeps track of the number of css's to be 4653 * cgroup_destroy_css_killed() will be invoked to perform the rest
4638 * killed and invokes cgroup_destroy_css_killed() to perform the 4654 * of destruction once the percpu refs of all css's are confirmed
4639 * rest of destruction once the percpu refs of all css's are 4655 * to be killed.
4640 * confirmed to be killed.
4641 */ 4656 */
4642 for_each_root_subsys(cgrp->root, ss) { 4657 for_each_root_subsys(cgrp->root, ss) {
4643 struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id); 4658 struct cgroup_subsys_state *css = cgroup_css(cgrp, ss->subsys_id);
@@ -4704,36 +4719,17 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
4704 * @work: cgroup->destroy_free_work 4719 * @work: cgroup->destroy_free_work
4705 * 4720 *
4706 * This function is invoked from a work item for a cgroup which is being 4721 * This function is invoked from a work item for a cgroup which is being
4707 * destroyed after the percpu refcnts of all css's are guaranteed to be 4722 * destroyed after all css's are offlined and performs the rest of
4708 * seen as killed on all CPUs, and performs the rest of destruction. This 4723 * destruction. This is the second step of destruction described in the
4709 * is the second step of destruction described in the comment above 4724 * comment above cgroup_destroy_locked().
4710 * cgroup_destroy_locked().
4711 */ 4725 */
4712static void cgroup_destroy_css_killed(struct cgroup *cgrp) 4726static void cgroup_destroy_css_killed(struct cgroup *cgrp)
4713{ 4727{
4714 struct cgroup *parent = cgrp->parent; 4728 struct cgroup *parent = cgrp->parent;
4715 struct dentry *d = cgrp->dentry; 4729 struct dentry *d = cgrp->dentry;
4716 struct cgroup_subsys *ss;
4717 4730
4718 lockdep_assert_held(&cgroup_mutex); 4731 lockdep_assert_held(&cgroup_mutex);
4719 4732
4720 /*
4721 * css_tryget() is guaranteed to fail now. Tell subsystems to
4722 * initate destruction.
4723 */
4724 for_each_root_subsys(cgrp->root, ss)
4725 offline_css(cgroup_css(cgrp, ss->subsys_id));
4726
4727 /*
4728 * Put the css refs from cgroup_destroy_locked(). Each css holds
4729 * an extra reference to the cgroup's dentry and cgroup removal
4730 * proceeds regardless of css refs. On the last put of each css,
4731 * whenever that may be, the extra dentry ref is put so that dentry
4732 * destruction happens only after all css's are released.
4733 */
4734 for_each_root_subsys(cgrp->root, ss)
4735 css_put(cgroup_css(cgrp, ss->subsys_id));
4736
4737 /* delete this cgroup from parent->children */ 4733 /* delete this cgroup from parent->children */
4738 list_del_rcu(&cgrp->sibling); 4734 list_del_rcu(&cgrp->sibling);
4739 4735