aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cgroup.h2
-rw-r--r--kernel/cgroup.c52
2 files changed, 25 insertions, 29 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 80dca872f4d4..71e77e7cdb6f 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -82,7 +82,7 @@ struct cgroup_subsys_state {
82 /* ID for this css, if possible */ 82 /* ID for this css, if possible */
83 struct css_id __rcu *id; 83 struct css_id __rcu *id;
84 84
85 /* Used to put @cgroup->dentry on the last css_put() */ 85 /* percpu_ref killing and putting dentry on the last css_put() */
86 struct work_struct destroy_work; 86 struct work_struct destroy_work;
87}; 87};
88 88
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