Skip to contentSkip to conversation

cgroup: use css->refcnt for cgroup reference counting

PATCH Applied Tejun Heo 3 participants 23 messages May 9, 2014 – May 16, 2014

Subsystems (2)
lore
Share & tools
lore

Tejun Heo

author maintainer
#0 lore raw

PATCH 1/1 cgroup: use css->refcnt for cgroup reference counting

Hello,

Currently, cgroup and css (cgroup_subsys_state) are separately reference counted. cgroup->refcnt is an atomic_t and css->refcnt is a percpu_ref. css is becoming the primary structural block and used widely in various operaitons. cgroup already has a css embedded in it (cgroup->dummy_css) to use as its proxy in such operations; however, there still are quite a few differences between cgroup and css handling limitng how cgroup->dummy_css can be used.

This patchset makes cgroup use the embedded css's refcnt for reference counting. This closes one of the gaps between an cgroup embedded css, which is renamed to cgroup->self early in the patchset, and a normal css and will allow more unified handling of cgroups and csses. In addition, this makes cgroup refcnting use percpu_ref too, which is a lot more scalable than an atomic_t.

Ultimately, it'd make things far simpler to assign a proper cgroup_subsys to the cgroup embedded csses and handle them the same as other csses; however, we can't yet do it thanks to multiple hierarchies as we end up with multiple csses of the same subsystem for the same task, but in the very long term, if multiple hierarchies can be removed, that's where it's headed.

This patchset contains the following nine patches.

0001-cgroup-use-restart_syscall-for-mount-retries.patch 0002-cgroup-rename-cgroup-dummy_css-to-self-and-move-it-t.patch 0003-cgroup-separate-out-cgroup_has_live_children-from-cg.patch 0004-cgroup-move-check_for_release-parent-call-to-the-end.patch 0005-cgroup-move-cgroup-sibling-unlinking-to-cgroup_put.patch 0006-cgroup-remove-cgroup_destory_css_killed.patch 0007-cgroup-bounce-css-release-through-css-destroy_work.patch 0008-cgroup-enable-refcnting-for-root-csses.patch 0009-cgroup-use-cgroup-self.refcnt-for-cgroup-refcnting.patch

0001-0003 are prep patches.

0004-0006 remove cgroup_destroy_css_killed(). This brings cgroup's destruction path closer to css's so that they can be merged.

0007-0009 make cgroup use the embedded css's refcnt.

This pachset is on top of

b9a63d0116e8 ("Merge branch 'for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu into for-3.16")
+ [1] [PATCHSET v2 cgroup/for-3.16] cgroup: post unified hierarchy fixes and updates
+ [2] (REFRESHED) [PATCHSET cgroup/for-3.16] cgroup: implement cftype->write()
+ [3] (REFRESHED) [PATCHSET cgroup/for-3.16] cgroup: remove cgroup_tree_mutex

and available in the following git branch.

git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-use-css-ref

diffstat follows. Thanks.

 include/linux/cgroup.h |   25 ----
 kernel/cgroup.c        |  284 ++++++++++++++++++++++---------------------------
 2 files changed, 136 insertions(+), 173 deletions(-)

--
tejun

[1] http://lkml.kernel.org/g/1399663975-315-1-git-send-email-tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
[2] http://lkml.kernel.org/g/20140509195059.GE4486-Gd/HAXX7CRxy/[email protected]
[3] http://lkml.kernel.org/g/20140509195827.GG4486-Gd/HAXX7CRxy/[email protected]

author maintainer
#1 lore raw

PATCH 1/9 cgroup: use restart_syscall() for mount retries

cgroup_mount() uses dumb delay-and-retry logic to wait for cgroup_root which is being destroyed. The retry currently loops inside cgroup_mount() proper. This patch makes it return with restart_syscall() instead so that retry travels out to userland boundary.

This slightly simplifies the logic and more importantly makes the retry logic behave better when the wait for some reason becomes lengthy or infinite by allowing the operation to be suspended or terminated from userland.

---
 kernel/cgroup.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
kernel/cgroup.c +2 -3
index 3083c5a..2755f33 100644
@@ -1681,7 +1681,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
 	ret = parse_cgroupfs_options(data, &opts);
 	if (ret)
 		goto out_unlock;
-retry:
+
 	/* look for a matching existing root */
 	if (!opts.subsys_mask && !opts.none && !opts.name) {
 		cgrp_dfl_root_visible = true;
@@ -1740,8 +1740,7 @@ retry:
 		if (!atomic_inc_not_zero(&root->cgrp.refcnt)) {
 			mutex_unlock(&cgroup_mutex);
 			msleep(10);
-			mutex_lock(&cgroup_mutex);
-			goto retry;
+			return ERR_PTR(restart_syscall());
 		}
 
 		ret = 0;
Signature · 1 line
1.9.0
#2 lore raw

Re: [PATCH 1/9] cgroup: use restart_syscall() for mount retries

Quoted 30 lines · Tejun Heo

cgroup_mount() uses dumb delay-and-retry logic to wait for cgroup_root which is being destroyed. The retry currently loops inside cgroup_mount() proper. This patch makes it return with restart_syscall() instead so that retry travels out to userland boundary.

This slightly simplifies the logic and more importantly makes the retry logic behave better when the wait for some reason becomes lengthy or infinite by allowing the operation to be suspended or terminated from userland.

---
 kernel/cgroup.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
kernel/cgroup.c +1 -1
index 3083c5a..2755f33 100644
@@ -1681,7 +1681,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
 	ret = parse_cgroupfs_options(data, &opts);
 	if (ret)
 		goto out_unlock;
-retry:
+
 	/* look for a matching existing root */
 	if (!opts.subsys_mask && !opts.none && !opts.name) {
 		cgrp_dfl_root_visible = true;

kernel/cgroup.c retry: · line 1743

Quoted 6 lines
kernel/cgroup.c +1 -2
@@ -1740,8 +1740,7 @@ retry:
 		if (!atomic_inc_not_zero(&root->cgrp.refcnt)) {
 			mutex_unlock(&cgroup_mutex);
 			msleep(10);
-			mutex_lock(&cgroup_mutex);
-			goto retry;
+			return ERR_PTR(restart_syscall());

We leak memory allocated in parse_cgroupfs_options().

author maintainer
#3 lore raw

PATCH v2 1/9 cgroup: use restart_syscall() for mount retries

In reply to Tejun Heo

cgroup_mount() uses dumb delay-and-retry logic to wait for cgroup_root which is being destroyed. The retry currently loops inside cgroup_mount() proper. This patch makes it return with restart_syscall() instead so that retry travels out to userland boundary.

This slightly simplifies the logic and more importantly makes the retry logic behave better when the wait for some reason becomes lengthy or infinite by allowing the operation to be suspended or terminated from userland.

v2: The original patch forgot to free memory allocated for @opts.
Fixed. Caught by Li Zefan.

---
 kernel/cgroup.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
kernel/cgroup.c +4 -4
@@ -1681,7 +1681,7 @@ static struct dentry *cgroup_mount(struc
 	ret = parse_cgroupfs_options(data, &opts);
 	if (ret)
 		goto out_unlock;
-retry:
+
 	/* look for a matching existing root */
 	if (!opts.subsys_mask && !opts.none && !opts.name) {
 		cgrp_dfl_root_visible = true;
@@ -1740,8 +1740,8 @@ retry:
 		if (!atomic_inc_not_zero(&root->cgrp.refcnt)) {
 			mutex_unlock(&cgroup_mutex);
 			msleep(10);
-			mutex_lock(&cgroup_mutex);
-			goto retry;
+			ret = restart_syscall();
+			goto out_free;
 		}
 
 		ret = 0;
@@ -1772,7 +1772,7 @@ retry:
 
 out_unlock:
 	mutex_unlock(&cgroup_mutex);
-
+out_free:
 	kfree(opts.release_agent);
 	kfree(opts.name);
 
author maintainer
#4 lore raw

PATCH 2/9 cgroup: rename cgroup->dummy_css to ->self and move it to the top

In reply to Tejun Heo

cgroup->dummy_css is used as the placeholder css when performing css oriended operations on the cgroup. We're gonna shift more cgroup management to this css. Let's rename it to ->self and move it to the top.

This is pure rename and field relocation.

---
 include/linux/cgroup.h |  6 +++---
 kernel/cgroup.c        | 20 ++++++++++----------
 2 files changed, 13 insertions(+), 13 deletions(-)
include/linux/cgroup.h +3 -3
index aa7353d..164851e 100644
@@ -143,6 +143,9 @@ enum {
 };
 
 struct cgroup {
+	/* self css with NULL ->ss, points back to this cgroup */
+	struct cgroup_subsys_state self;
+
 	unsigned long flags;		/* "unsigned long" so bitops work */
 
 	/*
@@ -224,9 +227,6 @@ struct cgroup {
 	struct list_head pidlists;
 	struct mutex pidlist_mutex;
 
-	/* dummy css with NULL ->ss, points back to this cgroup */
-	struct cgroup_subsys_state dummy_css;
-
 	/* For css percpu_ref killing and RCU-protected deletion */
 	struct rcu_head rcu_head;
 	struct work_struct destroy_work;
kernel/cgroup.c +10 -10
index 2755f33..b3708a8 100644
@@ -220,7 +220,7 @@ static void cgroup_idr_remove(struct idr *idr, int id)
 /**
  * cgroup_css - obtain a cgroup's css for the specified subsystem
  * @cgrp: the cgroup of interest
- * @ss: the subsystem of interest (%NULL returns the dummy_css)
+ * @ss: the subsystem of interest (%NULL returns @cgrp->self)
  *
  * Return @cgrp's css (cgroup_subsys_state) associated with @ss.  This
  * function must be called either under cgroup_mutex or rcu_read_lock() and
@@ -235,13 +235,13 @@ static struct cgroup_subsys_state *cgroup_css(struct cgroup *cgrp,
 		return rcu_dereference_check(cgrp->subsys[ss->id],
 					lockdep_is_held(&cgroup_mutex));
 	else
-		return &cgrp->dummy_css;
+		return &cgrp->self;
 }
 
 /**
  * cgroup_e_css - obtain a cgroup's effective css for the specified subsystem
  * @cgrp: the cgroup of interest
- * @ss: the subsystem of interest (%NULL returns the dummy_css)
+ * @ss: the subsystem of interest (%NULL returns @cgrp->self)
  *
  * Similar to cgroup_css() but returns the effctive css, which is defined
  * as the matching css of the nearest ancestor including self which has @ss
@@ -254,7 +254,7 @@ static struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp,
 	lockdep_assert_held(&cgroup_mutex);
 
 	if (!ss)
-		return &cgrp->dummy_css;
+		return &cgrp->self;
 
 	if (!(cgrp->root->subsys_mask & (1 << ss->id)))
 		return NULL;
@@ -288,7 +288,7 @@ struct cgroup_subsys_state *of_css(struct kernfs_open_file *of)
 	if (cft->ss)
 		return rcu_dereference_raw(cgrp->subsys[cft->ss->id]);
 	else
-		return &cgrp->dummy_css;
+		return &cgrp->self;
 }
 EXPORT_SYMBOL_GPL(of_css);
 
@@ -1551,7 +1551,7 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp)
 	INIT_LIST_HEAD(&cgrp->release_list);
 	INIT_LIST_HEAD(&cgrp->pidlists);
 	mutex_init(&cgrp->pidlist_mutex);
-	cgrp->dummy_css.cgroup = cgrp;
+	cgrp->self.cgroup = cgrp;
 
 	for_each_subsys(ss, ssid)
 		INIT_LIST_HEAD(&cgrp->e_csets[ssid]);
@@ -3453,7 +3453,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
 	 * ->can_attach() fails.
 	 */
 	do {
-		css_task_iter_start(&from->dummy_css, &it);
+		css_task_iter_start(&from->self, &it);
 		task = css_task_iter_next(&it);
 		if (task)
 			get_task_struct(task);
@@ -3718,7 +3718,7 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type,
 	if (!array)
 		return -ENOMEM;
 	/* now, populate the array */
-	css_task_iter_start(&cgrp->dummy_css, &it);
+	css_task_iter_start(&cgrp->self, &it);
 	while ((tsk = css_task_iter_next(&it))) {
 		if (unlikely(n == length))
 			break;
@@ -3792,7 +3792,7 @@ int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry)
 	}
 	rcu_read_unlock();
 
-	css_task_iter_start(&cgrp->dummy_css, &it);
+	css_task_iter_start(&cgrp->self, &it);
 	while ((tsk = css_task_iter_next(&it))) {
 		switch (tsk->state) {
 		case TASK_RUNNING:
@@ -4273,7 +4273,7 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
 	init_cgroup_housekeeping(cgrp);
 
 	cgrp->parent = parent;
-	cgrp->dummy_css.parent = &parent->dummy_css;
+	cgrp->self.parent = &parent->self;
 	cgrp->root = root;
 
 	if (notify_on_release(parent))
Signature · 1 line
1.9.0
author maintainer
#5 lore raw

PATCH 3/9 cgroup: separate out cgroup_has_live_children() from cgroup_destroy_locked()

In reply to Tejun Heo

We're expecting another user.

---
 kernel/cgroup.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)
kernel/cgroup.c +16 -10
index b3708a8..d369f19 100644
@@ -3294,6 +3294,21 @@ css_next_descendant_post(struct cgroup_subsys_state *pos,
 	return css_parent(pos);
 }
 
+static bool cgroup_has_live_children(struct cgroup *cgrp)
+{
+	struct cgroup *child;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(child, &cgrp->children, sibling) {
+		if (!cgroup_is_dead(child)) {
+			rcu_read_unlock();
+			return true;
+		}
+	}
+	rcu_read_unlock();
+	return false;
+}
+
 /**
  * css_advance_task_iter - advance a task itererator to the next css_set
  * @it: the iterator to advance
@@ -4464,7 +4479,6 @@ static void kill_css(struct cgroup_subsys_state *css)
 static int cgroup_destroy_locked(struct cgroup *cgrp)
 	__releases(&cgroup_mutex) __acquires(&cgroup_mutex)
 {
-	struct cgroup *child;
 	struct cgroup_subsys_state *css;
 	bool empty;
 	int ssid;
@@ -4486,15 +4500,7 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
 	 * emptiness as dead children linger on it while being destroyed;
 	 * otherwise, "rmdir parent/child parent" may fail with -EBUSY.
 	 */
-	empty = true;
-	rcu_read_lock();
-	list_for_each_entry_rcu(child, &cgrp->children, sibling) {
-		empty = cgroup_is_dead(child);
-		if (!empty)
-			break;
-	}
-	rcu_read_unlock();
-	if (!empty)
+	if (cgroup_has_live_children(cgrp))
 		return -EBUSY;
 
 	/*
Signature · 1 line
1.9.0
author maintainer
#6 lore raw

PATCH 4/9 cgroup: move check_for_release(parent) call to the end of cgroup_destroy_locked()

In reply to Tejun Heo

Currently, check_for_release() on the parent of a destroyed cgroup is invoked from cgroup_destroy_css_killed(). This is because this is where the destroyed cgroup can be removed from the parent's children list. check_for_release() tests the emptiness of the list directly, so invoking it before removing the cgroup from the list makes it think that the parent still has children even when it no longer does.

This patch updates check_for_release() to use cgroup_has_live_children() instead of directly testing ->children emptiness and moves check_for_release(parent) earlier to the end of cgroup_destroy_locked(). As cgroup_has_live_children() ignores cgroups marked DEAD, check_for_release() functions correctly as long as it's called after asserting DEAD.

This makes release notification slightly more timely and more importantly enables further simplification of cgroup destruction path.

---
 kernel/cgroup.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
kernel/cgroup.c +4 -6
index d369f19..45149b7 100644
@@ -4541,6 +4541,9 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
 	 */
 	kernfs_remove(cgrp->kn);
 
+	set_bit(CGRP_RELEASABLE, &cgrp->parent->flags);
+	check_for_release(cgrp->parent);
+
 	return 0;
 };
 
@@ -4555,17 +4558,12 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
  */
 static void cgroup_destroy_css_killed(struct cgroup *cgrp)
 {
-	struct cgroup *parent = cgrp->parent;
-
 	lockdep_assert_held(&cgroup_mutex);
 
 	/* delete this cgroup from parent->children */
 	list_del_rcu(&cgrp->sibling);
 
 	cgroup_put(cgrp);
-
-	set_bit(CGRP_RELEASABLE, &parent->flags);
-	check_for_release(parent);
 }
 
 static int cgroup_rmdir(struct kernfs_node *kn)
@@ -5005,7 +5003,7 @@ void cgroup_exit(struct task_struct *tsk)
 static void check_for_release(struct cgroup *cgrp)
 {
 	if (cgroup_is_releasable(cgrp) &&
-	    list_empty(&cgrp->cset_links) && list_empty(&cgrp->children)) {
+	    list_empty(&cgrp->cset_links) && !cgroup_has_live_children(cgrp)) {
 		/*
 		 * Control Group is currently removeable. If it's not
 		 * already queued for a userspace notification, queue
Signature · 1 line
1.9.0
author maintainer
#7 lore raw

PATCH 5/9 cgroup: move cgroup->sibling unlinking to cgroup_put()

In reply to Tejun Heo

Move cgroup->sibling unlinking from cgroup_destroy_css_killed() to cgroup_put(). This is later but still before the RCU grace period, so it doesn't break css_next_child() although there now is a larger window in which a dead cgroup is visible during css iteration. As css iteration always could have included offline csses, this doesn't affect correctness; however, it does make css_next_child() fall back to reiterting mode more often. This also makes cgroup_put() directly take cgroup_mutex, which limits where it can be called from. These are not immediately problematic and will be dealt with later.

This change enables simplification of cgroup destruction path.

---
 kernel/cgroup.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
kernel/cgroup.c +5 -3
index 45149b7..87ea2ce 100644
@@ -1056,6 +1056,11 @@ static void cgroup_put(struct cgroup *cgrp)
 	if (WARN_ON_ONCE(cgrp->parent && !cgroup_is_dead(cgrp)))
 		return;
 
+	/* delete this cgroup from parent->children */
+	mutex_lock(&cgroup_mutex);
+	list_del_rcu(&cgrp->sibling);
+	mutex_unlock(&cgroup_mutex);
+
 	cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
 	cgrp->id = -1;
 
@@ -4560,9 +4565,6 @@ static void cgroup_destroy_css_killed(struct cgroup *cgrp)
 {
 	lockdep_assert_held(&cgroup_mutex);
 
-	/* delete this cgroup from parent->children */
-	list_del_rcu(&cgrp->sibling);
-
 	cgroup_put(cgrp);
 }
 
Signature · 1 line
1.9.0
author maintainer
#8 lore raw

PATCH 6/9 cgroup: remove cgroup_destory_css_killed()

In reply to Tejun Heo

cgroup_destroy_css_killed() is cgroup destruction stage which happens after all csses are offlined. After the recent updates, it no longer does anything other than putting the base reference. This patch removes the function and makes cgroup_destroy_locked() put the base ref at the end isntead.

This also makes cgroup->nr_css unnecessary. Removed.

---
 include/linux/cgroup.h |  3 ---
 kernel/cgroup.c        | 62 +++++---------------------------------------------
 2 files changed, 6 insertions(+), 59 deletions(-)
include/linux/cgroup.h +0 -3
index 164851e..160fcc6 100644
@@ -158,9 +158,6 @@ struct cgroup {
 	 */
 	int id;
 
-	/* the number of attached css's */
-	int nr_css;
-
 	/*
 	 * If this cgroup contains any tasks, it contributes one to
 	 * populated_cnt.  All children with non-zero popuplated_cnt of
kernel/cgroup.c +6 -56

117 lines not on this page · raw message

Signature · 1 line
1.9.0
author maintainer
#9 lore raw

PATCH 7/9 cgroup: bounce css release through css->destroy_work

In reply to Tejun Heo

css release is planned to do more and would require process context. Bounce it through css->destroy_work.

---
 kernel/cgroup.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
kernel/cgroup.c +11 -2
index bb67acb..b382383 100644
@@ -4125,10 +4125,10 @@ static void css_free_rcu_fn(struct rcu_head *rcu_head)
 	queue_work(cgroup_destroy_wq, &css->destroy_work);
 }
 
-static void css_release(struct percpu_ref *ref)
+static void css_release_work_fn(struct work_struct *work)
 {
 	struct cgroup_subsys_state *css =
-		container_of(ref, struct cgroup_subsys_state, refcnt);
+		container_of(work, struct cgroup_subsys_state, destroy_work);
 	struct cgroup_subsys *ss = css->ss;
 
 	cgroup_idr_remove(&ss->css_idr, css->id);
@@ -4136,6 +4136,15 @@ static void css_release(struct percpu_ref *ref)
 	call_rcu(&css->rcu_head, css_free_rcu_fn);
 }
 
+static void css_release(struct percpu_ref *ref)
+{
+	struct cgroup_subsys_state *css =
+		container_of(ref, struct cgroup_subsys_state, refcnt);
+
+	INIT_WORK(&css->destroy_work, css_release_work_fn);
+	queue_work(cgroup_destroy_wq, &css->destroy_work);
+}
+
 static void init_and_link_css(struct cgroup_subsys_state *css,
 			      struct cgroup_subsys *ss, struct cgroup *cgrp)
 {
Signature · 1 line
1.9.0
author maintainer
#10 lore raw

PATCH 8/9 cgroup: enable refcnting for root csses

In reply to Tejun Heo

Currently, css_get(), css_tryget() and css_tryget_online() are noops for root csses as an optimization; however, we're planning to use css refcnts to track of cgroup lifetime too and root cgroups also need to be reference counted. Since css has been converted to percpu_refcnt, the overhead of refcnting is miniscule and this optimization isn't too meaningful anymore. Furthermore, controllers which optimize the root cgroup often never even invoke these functions in their hot paths.

This patch enables refcnting for root csses too. This makes CSS_ROOT flag unused and removes it.

---
 include/linux/cgroup.h | 10 ++--------
 kernel/cgroup.c        |  6 +++---
 2 files changed, 5 insertions(+), 11 deletions(-)
include/linux/cgroup.h +2 -8
index 160fcc6..286e39e 100644
@@ -77,7 +77,6 @@ struct cgroup_subsys_state {
 
 /* bits in struct cgroup_subsys_state flags field */
 enum {
-	CSS_ROOT	= (1 << 0), /* this CSS is the root of the subsystem */
 	CSS_ONLINE	= (1 << 1), /* between ->css_online() and ->css_offline() */
 };
 
@@ -89,9 +88,7 @@ enum {
  */
 static inline void css_get(struct cgroup_subsys_state *css)
 {
-	/* We don't need to reference count the root state */
-	if (!(css->flags & CSS_ROOT))
-		percpu_ref_get(&css->refcnt);
+	percpu_ref_get(&css->refcnt);
 }
 
 /**
@@ -106,8 +103,6 @@ static inline void css_get(struct cgroup_subsys_state *css)
  */
 static inline bool css_tryget_online(struct cgroup_subsys_state *css)
 {
-	if (css->flags & CSS_ROOT)
-		return true;
 	return percpu_ref_tryget_live(&css->refcnt);
 }
 
@@ -119,8 +114,7 @@ static inline bool css_tryget_online(struct cgroup_subsys_state *css)
  */
 static inline void css_put(struct cgroup_subsys_state *css)
 {
-	if (!(css->flags & CSS_ROOT))
-		percpu_ref_put(&css->refcnt);
+	percpu_ref_put(&css->refcnt);
 }
 
 /* bits in struct cgroup flags field */
kernel/cgroup.c +3 -3
index b382383..5a31e61 100644
@@ -4157,8 +4157,6 @@ static void init_and_link_css(struct cgroup_subsys_state *css,
 	if (cgrp->parent) {
 		css->parent = cgroup_css(cgrp->parent, ss);
 		css_get(css->parent);
-	} else {
-		css->flags |= CSS_ROOT;
 	}
 
 	BUG_ON(cgroup_css(cgrp, ss));
@@ -4581,9 +4579,10 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
 	BUG_ON(IS_ERR(css));
 	init_and_link_css(css, ss, &cgrp_dfl_root.cgrp);
 	if (early) {
-		/* idr_alloc() can't be called safely during early init */
+		/* allocation can't be done safely during early init */
 		css->id = 1;
 	} else {
+		BUG_ON(percpu_ref_init(&css->refcnt, css_release));
 		css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2, GFP_KERNEL);
 		BUG_ON(css->id < 0);
 	}
@@ -4670,6 +4669,7 @@ int __init cgroup_init(void)
 			struct cgroup_subsys_state *css =
 				init_css_set.subsys[ss->id];
 
+			BUG_ON(percpu_ref_init(&css->refcnt, css_release));
 			css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2,
 						   GFP_KERNEL);
 			BUG_ON(css->id < 0);
Signature · 1 line
1.9.0
author maintainer
#11 lore raw

PATCH 9/9 cgroup: use cgroup->self.refcnt for cgroup refcnting

In reply to Tejun Heo

Currently cgroup implements refcnting separately using atomic_t cgroup->refcnt. The destruction paths of cgroup and css are rather complex and bear a lot of similiarities including the use of RCU and bouncing to a work item.

This patch makes cgroup use the refcnt of self css for refcnting instead of using its own. This makes cgroup refcnting use css's percpu refcnt and share the destruction mechanism.

* css_release_work_fn() and css_free_work_fn() are updated to handle both csses and cgroups. This is a bit messy but should do until we can make cgroup->self a full css, which currently can't be done thanks to multiple hierarchies.

* cgroup_destroy_locked() now performs percpu_ref_kill(&cgrp->self.refcnt) instead of cgroup_put(cgrp).

* Negative refcnt sanity check in cgroup_get() is no longer necessary as percpu_ref already handles it.

* Similarly, as a cgroup which hasn't been killed will never be released regardless of its refcnt value and percpu_ref has sanity check on kill, cgroup_is_dead() sanity check in cgroup_put() is no longer necessary.

* As whether a refcnt reached zero or not can only be decided after the reference count is killed, cgroup_root->cgrp's refcnting can no longer be used to decide whether to kill the root or not. Let's make cgroup_kill_sb() explicitly initiate destruction if the root doesn't have any children. This makes sense anyway as unmounted cgroup hierarchy without any children should be destroyed.

While this is a bit messy, this will allow pushing more bookkeeping towards cgroup->self and thus handling cgroups and csses in more uniform way. In the very long term, it should be possible to introduce a base subsystem and convert the self css to a proper one making things whole lot simpler and unified.

---
 include/linux/cgroup.h |   6 --
 kernel/cgroup.c        | 146 +++++++++++++++++++++++++++----------------------
 2 files changed, 80 insertions(+), 72 deletions(-)
include/linux/cgroup.h +0 -6
index 286e39e..76dadd77 100644
@@ -160,8 +160,6 @@ struct cgroup {
 	 */
 	int populated_cnt;
 
-	atomic_t refcnt;
-
 	/*
 	 * We link our 'sibling' struct into our parent's 'children'.
 	 * Our children link their 'sibling' into our 'children'.
@@ -218,10 +216,6 @@ struct cgroup {
 	struct list_head pidlists;
 	struct mutex pidlist_mutex;
 
-	/* For css percpu_ref killing and RCU-protected deletion */
-	struct rcu_head rcu_head;
-	struct work_struct destroy_work;
-
 	/* used to wait for offlining of csses */
 	wait_queue_head_t offline_waitq;
 };
kernel/cgroup.c +80 -66

247 lines not on this page · raw message

Signature · 1 line
1.9.0
#12 lore raw

Re: [PATCH 9/9] cgroup: use cgroup->self.refcnt for cgroup refcnting

Quoted 9 lines · Tejun Heo

Currently cgroup implements refcnting separately using atomic_t cgroup->refcnt. The destruction paths of cgroup and css are rather complex and bear a lot of similiarities including the use of RCU and bouncing to a work item.

This patch makes cgroup use the refcnt of self css for refcnting instead of using its own. This makes cgroup refcnting use css's percpu refcnt and share the destruction mechanism.
...

In next-20150515, this patch causes silent boot failures on NVIDIA Tegra ARM systems. There isn't even any earlyprintk. Reverting this one patch solves this.

I was a bit surprised that cgroups would cause such an issue, but looking at a normal kernel boot, I guess cgroup does get initialized very early:

Uncompressing Linux... done, booting the kernel.

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct

Anyway, I'll try to track down what the problem is, but if someone familiar with this patch could give it a look, that'd be very useful, since I'm not at all familiar with this code or feature.

#13 lore raw

Re: [PATCH 9/9] cgroup: use cgroup->self.refcnt for cgroup refcnting

Quoted 19 lines · Stephen Warren
Quoted 9 lines · Tejun Heo

Currently cgroup implements refcnting separately using atomic_t cgroup->refcnt. The destruction paths of cgroup and css are rather complex and bear a lot of similiarities including the use of RCU and bouncing to a work item.

This patch makes cgroup use the refcnt of self css for refcnting instead of using its own. This makes cgroup refcnting use css's percpu refcnt and share the destruction mechanism.
...

In next-20150515, this patch causes silent boot failures on NVIDIA Tegra ARM systems. There isn't even any earlyprintk. Reverting this one patch solves this.

I was a bit surprised that cgroups would cause such an issue, but looking at a normal kernel boot, I guess cgroup does get initialized very early:

Quoted 8 lines

Uncompressing Linux... done, booting the kernel.

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct

Anyway, I'll try to track down what the problem is, but if someone familiar with this patch could give it a look, that'd be very useful, since I'm not at all familiar with this code or feature.

It looks like this has something to do with the new code using percpu_ functions from within cgroup_init_early, yet that function being called before init/main.c calls setup_per_cpu_areas() etc.? Unfortunately I have to run to some meetings now, so won't look at this until tomorrow.

author maintainer
#14 lore raw

Re: [PATCH 9/9] cgroup: use cgroup->self.refcnt for cgroup refcnting

Hello, Stephen.

Quoted 25 lines · Stephen Warren
Quoted 24 lines · Stephen Warren
Quoted 9 lines · Tejun Heo

Currently cgroup implements refcnting separately using atomic_t cgroup->refcnt. The destruction paths of cgroup and css are rather complex and bear a lot of similiarities including the use of RCU and bouncing to a work item.

This patch makes cgroup use the refcnt of self css for refcnting instead of using its own. This makes cgroup refcnting use css's percpu refcnt and share the destruction mechanism.
...

In next-20150515, this patch causes silent boot failures on NVIDIA Tegra ARM systems. There isn't even any earlyprintk. Reverting this one patch solves this.

I was a bit surprised that cgroups would cause such an issue, but looking at a normal kernel boot, I guess cgroup does get initialized very early:

Uncompressing Linux... done, booting the kernel.

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
Quoted 8 lines
Quoted 3 lines

Anyway, I'll try to track down what the problem is, but if someone familiar with this patch could give it a look, that'd be very useful, since I'm not at all familiar with this code or feature.

It looks like this has something to do with the new code using percpu_ functions from within cgroup_init_early, yet that function being called before init/main.c calls setup_per_cpu_areas() etc.? Unfortunately I have to run to some meetings now, so won't look at this until tomorrow.

Yeap, I know where the issue is. Will post a fix soon.

Thanks.

Signature · 1 line
tejun
author maintainer
#15 lore raw

PATCH 1/1 cgroup: introduce CSS_NO_REF and skip refcnting on normal root csses

From 49035d695d8f1c4bbe4e37480e5d06812818947c Mon Sep 17 00:00:00 2001
From: Tejun Heo <[email protected]>
Date: Fri, 16 May 2014 11:40:33 -0400

9395a4500404 ("cgroup: enable refcnting for root csses") enabled reference counting for root csses (cgroup_subsys_states) so that cgroup's self csses can be used to manage the lifetime of the containing cgroups.

Unfortunately, this change was incorrect. cpu controller uses early_init and starts using css reference counts on its root css from then on. percpu_ref can't initialized during early init and its initialization is deferred till cgroup_init() time. This means that cpu was using percpu_ref which wasn't properly initialized. Due to the way percpu variables are laid out on x86, this didn't blow up immediately on x86 but ended up incrementing and decrementing the percpu variable at offset zero, whatever it may be; however, on other archs, this caused fault and early boot failure.

As cgroup self csses still need working refcounting, we can't revert 9395a4500404. This patch adds CSS_NO_REF which explicitly inhibits reference counting on the css and sets it on all normal (non-self) csses.

Fixes 9395a4500404 ("cgroup: enable refcnting for root csses")

---
Patch applied to cgroup/for-3.16.

Thanks.

 include/linux/cgroup.h | 11 ++++++++---
 kernel/cgroup.c        |  9 +++++++--
 2 files changed, 15 insertions(+), 5 deletions(-)
include/linux/cgroup.h +8 -3
index 76dadd77..1737db0 100644
@@ -77,6 +77,7 @@ struct cgroup_subsys_state {
 
 /* bits in struct cgroup_subsys_state flags field */
 enum {
+	CSS_NO_REF	= (1 << 0), /* no reference counting for this css */
 	CSS_ONLINE	= (1 << 1), /* between ->css_online() and ->css_offline() */
 };
 
@@ -88,7 +89,8 @@ enum {
  */
 static inline void css_get(struct cgroup_subsys_state *css)
 {
-	percpu_ref_get(&css->refcnt);
+	if (!(css->flags & CSS_NO_REF))
+		percpu_ref_get(&css->refcnt);
 }
 
 /**
@@ -103,7 +105,9 @@ static inline void css_get(struct cgroup_subsys_state *css)
  */
 static inline bool css_tryget_online(struct cgroup_subsys_state *css)
 {
-	return percpu_ref_tryget_live(&css->refcnt);
+	if (!(css->flags & CSS_NO_REF))
+		return percpu_ref_tryget_live(&css->refcnt);
+	return true;
 }
 
 /**
@@ -114,7 +118,8 @@ static inline bool css_tryget_online(struct cgroup_subsys_state *css)
  */
 static inline void css_put(struct cgroup_subsys_state *css)
 {
-	percpu_ref_put(&css->refcnt);
+	if (!(css->flags & CSS_NO_REF))
+		percpu_ref_put(&css->refcnt);
 }
 
 /* bits in struct cgroup flags field */
kernel/cgroup.c +7 -2
index c01e8e8..ad15bb7 100644
@@ -4593,11 +4593,17 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
 	/* We don't handle early failures gracefully */
 	BUG_ON(IS_ERR(css));
 	init_and_link_css(css, ss, &cgrp_dfl_root.cgrp);
+
+	/*
+	 * Root csses are never destroyed and we can't initialize
+	 * percpu_ref during early init.  Disable refcnting.
+	 */
+	css->flags |= CSS_NO_REF;
+
 	if (early) {
 		/* allocation can't be done safely during early init */
 		css->id = 1;
 	} else {
-		BUG_ON(percpu_ref_init(&css->refcnt, css_release));
 		css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2, GFP_KERNEL);
 		BUG_ON(css->id < 0);
 	}
@@ -4684,7 +4690,6 @@ int __init cgroup_init(void)
 			struct cgroup_subsys_state *css =
 				init_css_set.subsys[ss->id];
 
-			BUG_ON(percpu_ref_init(&css->refcnt, css_release));
 			css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2,
 						   GFP_KERNEL);
 			BUG_ON(css->id < 0);
Signature · 1 line
1.9.0
#16 lore raw

Re: [PATCH cgroup/for-3.16] cgroup: introduce CSS_NO_REF and skip refcnting on normal root csses

Quoted 24 lines · Tejun Heo

From 49035d695d8f1c4bbe4e37480e5d06812818947c Mon Sep 17 00:00:00 2001
From: Tejun Heo <[email protected]>
Date: Fri, 16 May 2014 11:40:33 -0400

9395a4500404 ("cgroup: enable refcnting for root csses") enabled reference counting for root csses (cgroup_subsys_states) so that cgroup's self csses can be used to manage the lifetime of the containing cgroups.

Unfortunately, this change was incorrect. cpu controller uses early_init and starts using css reference counts on its root css from then on. percpu_ref can't initialized during early init and its initialization is deferred till cgroup_init() time. This means that cpu was using percpu_ref which wasn't properly initialized. Due to the way percpu variables are laid out on x86, this didn't blow up immediately on x86 but ended up incrementing and decrementing the percpu variable at offset zero, whatever it may be; however, on other archs, this caused fault and early boot failure.

As cgroup self csses still need working refcounting, we can't revert 9395a4500404. This patch adds CSS_NO_REF which explicitly inhibits reference counting on the css and sets it on all normal (non-self) csses.

Quoted 5 lines
Fixes 9395a4500404 ("cgroup: enable refcnting for root csses")

---
Patch applied to cgroup/for-3.16.

Unfortunately, this patch doesn't seem to solve the problem for me. I still get a hang/crash very early during boot, before earlyprintk stars.

I tried this patch on top of both next-20150115, and next-20150516. For both those kernels, reverting the original problematic patch does resolve the problem.

I'll try to investigate more later today.

author maintainer
#17 lore raw

PATCH v2 1/1 cgroup: introduce CSS_NO_REF and skip refcnting on normal root csses

9395a4500404 ("cgroup: enable refcnting for root csses") enabled reference counting for root csses (cgroup_subsys_states) so that cgroup's self csses can be used to manage the lifetime of the containing cgroups.

Unfortunately, this change was incorrect. During early init, cgrp_dfl_root self css refcnt is used. percpu_ref can't initialized during early init and its initialization is deferred till cgroup_init() time. This means that cpu was using percpu_ref which wasn't properly initialized. Due to the way percpu variables are laid out on x86, this didn't blow up immediately on x86 but ended up incrementing and decrementing the percpu variable at offset zero, whatever it may be; however, on other archs, this caused fault and early boot failure.

As cgroup self csses for root cgroups of non-dfl hierarchies need working refcounting, we can't revert 9395a4500404. This patch adds CSS_NO_REF which explicitly inhibits reference counting on the css and sets it on all normal (non-self) csses and cgroup_dfl_root self css.

v2: cgrp_dfl_root.self is the offending one. Set the flag on it.

Fixes 9395a4500404 ("cgroup: enable refcnting for root csses")

---
Hello,

Can you try this one instead?

Thanks.

 include/linux/cgroup.h |   11 ++++++++---
 kernel/cgroup.c        |   11 +++++++++--
 2 files changed, 17 insertions(+), 5 deletions(-)
include/linux/cgroup.h +8 -3
@@ -77,6 +77,7 @@ struct cgroup_subsys_state {
 
 /* bits in struct cgroup_subsys_state flags field */
 enum {
+	CSS_NO_REF	= (1 << 0), /* no reference counting for this css */
 	CSS_ONLINE	= (1 << 1), /* between ->css_online() and ->css_offline() */
 };
 
@@ -88,7 +89,8 @@ enum {
  */
 static inline void css_get(struct cgroup_subsys_state *css)
 {
-	percpu_ref_get(&css->refcnt);
+	if (!(css->flags & CSS_NO_REF))
+		percpu_ref_get(&css->refcnt);
 }
 
 /**
@@ -103,7 +105,9 @@ static inline void css_get(struct cgroup
  */
 static inline bool css_tryget_online(struct cgroup_subsys_state *css)
 {
-	return percpu_ref_tryget_live(&css->refcnt);
+	if (!(css->flags & CSS_NO_REF))
+		return percpu_ref_tryget_live(&css->refcnt);
+	return true;
 }
 
 /**
@@ -114,7 +118,8 @@ static inline bool css_tryget_online(str
  */
 static inline void css_put(struct cgroup_subsys_state *css)
 {
-	percpu_ref_put(&css->refcnt);
+	if (!(css->flags & CSS_NO_REF))
+		percpu_ref_put(&css->refcnt);
 }
 
 /* bits in struct cgroup flags field */
kernel/cgroup.c +9 -2
@@ -4593,11 +4593,17 @@ static void __init cgroup_init_subsys(st
 	/* We don't handle early failures gracefully */
 	BUG_ON(IS_ERR(css));
 	init_and_link_css(css, ss, &cgrp_dfl_root.cgrp);
+
+	/*
+	 * Root csses are never destroyed and we can't initialize
+	 * percpu_ref during early init.  Disable refcnting.
+	 */
+	css->flags |= CSS_NO_REF;
+
 	if (early) {
 		/* allocation can't be done safely during early init */
 		css->id = 1;
 	} else {
-		BUG_ON(percpu_ref_init(&css->refcnt, css_release));
 		css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2, GFP_KERNEL);
 		BUG_ON(css->id < 0);
 	}
@@ -4636,6 +4642,8 @@ int __init cgroup_init_early(void)
 	int i;
 
 	init_cgroup_root(&cgrp_dfl_root, &opts);
+	cgrp_dfl_root.cgrp.self.flags |= CSS_NO_REF;
+
 	RCU_INIT_POINTER(init_task.cgroups, &init_css_set);
 
 	for_each_subsys(ss, i) {
@@ -4684,7 +4692,6 @@ int __init cgroup_init(void)
 			struct cgroup_subsys_state *css =
 				init_css_set.subsys[ss->id];
 
-			BUG_ON(percpu_ref_init(&css->refcnt, css_release));
 			css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2,
 						   GFP_KERNEL);
 			BUG_ON(css->id < 0);
Tested-by on v2 1/1
#18 lore raw

Re: [PATCH v2 cgroup/for-3.16] cgroup: introduce CSS_NO_REF and skip refcnting on normal root csses

Quoted 22 lines · Tejun Heo

9395a4500404 ("cgroup: enable refcnting for root csses") enabled reference counting for root csses (cgroup_subsys_states) so that cgroup's self csses can be used to manage the lifetime of the containing cgroups.

Unfortunately, this change was incorrect. During early init, cgrp_dfl_root self css refcnt is used. percpu_ref can't initialized during early init and its initialization is deferred till cgroup_init() time. This means that cpu was using percpu_ref which wasn't properly initialized. Due to the way percpu variables are laid out on x86, this didn't blow up immediately on x86 but ended up incrementing and decrementing the percpu variable at offset zero, whatever it may be; however, on other archs, this caused fault and early boot failure.

As cgroup self csses for root cgroups of non-dfl hierarchies need working refcounting, we can't revert 9395a4500404. This patch adds CSS_NO_REF which explicitly inhibits reference counting on the css and sets it on all normal (non-self) csses and cgroup_dfl_root self css.

v2: cgrp_dfl_root.self is the offending one. Set the flag on it.

Quoted 7 lines
Fixes 9395a4500404 ("cgroup: enable refcnting for root csses")

---
Hello,

Can you try this one instead?

Yes, this one works great, thanks.

author maintainer
#19 lore raw

Re: [PATCH v2 cgroup/for-3.16] cgroup: introduce CSS_NO_REF and skip refcnting on normal root csses

Quoted 5 lines · Stephen Warren
Quoted 1 line · Tejun Heo

Can you try this one instead?

Yes, this one works great, thanks.

Thanks, I reverted the original one and applied the updated one w/ your Tested-by tag added.

Signature · 1 line
tejun
author maintainer
#20 lore raw
In reply to Tejun Heo
Quoted 3 lines · Tejun Heo

and available in the following git branch.

git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-use-css-ref

Rebased on top of cgroup/for-3.16.

Thanks.

Signature · 1 line
tejun
Acked-by on v1 1/1
#21 lore raw
In reply to Tejun Heo
Quoted 52 lines · Tejun Heo

Hello,

Currently, cgroup and css (cgroup_subsys_state) are separately reference counted. cgroup->refcnt is an atomic_t and css->refcnt is a percpu_ref. css is becoming the primary structural block and used widely in various operaitons. cgroup already has a css embedded in it (cgroup->dummy_css) to use as its proxy in such operations; however, there still are quite a few differences between cgroup and css handling limitng how cgroup->dummy_css can be used.

This patchset makes cgroup use the embedded css's refcnt for reference counting. This closes one of the gaps between an cgroup embedded css, which is renamed to cgroup->self early in the patchset, and a normal css and will allow more unified handling of cgroups and csses. In addition, this makes cgroup refcnting use percpu_ref too, which is a lot more scalable than an atomic_t.

Ultimately, it'd make things far simpler to assign a proper cgroup_subsys to the cgroup embedded csses and handle them the same as other csses; however, we can't yet do it thanks to multiple hierarchies as we end up with multiple csses of the same subsystem for the same task, but in the very long term, if multiple hierarchies can be removed, that's where it's headed.

This patchset contains the following nine patches.

0001-cgroup-use-restart_syscall-for-mount-retries.patch 0002-cgroup-rename-cgroup-dummy_css-to-self-and-move-it-t.patch 0003-cgroup-separate-out-cgroup_has_live_children-from-cg.patch 0004-cgroup-move-check_for_release-parent-call-to-the-end.patch 0005-cgroup-move-cgroup-sibling-unlinking-to-cgroup_put.patch 0006-cgroup-remove-cgroup_destory_css_killed.patch 0007-cgroup-bounce-css-release-through-css-destroy_work.patch 0008-cgroup-enable-refcnting-for-root-csses.patch 0009-cgroup-use-cgroup-self.refcnt-for-cgroup-refcnting.patch

0001-0003 are prep patches.

0004-0006 remove cgroup_destroy_css_killed(). This brings cgroup's destruction path closer to css's so that they can be merged.

0007-0009 make cgroup use the embedded css's refcnt.

This pachset is on top of

b9a63d0116e8 ("Merge branch 'for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu into for-3.16")
+ [1] [PATCHSET v2 cgroup/for-3.16] cgroup: post unified hierarchy fixes and updates
+ [2] (REFRESHED) [PATCHSET cgroup/for-3.16] cgroup: implement cftype->write()
+ [3] (REFRESHED) [PATCHSET cgroup/for-3.16] cgroup: remove cgroup_tree_mutex

and available in the following git branch.

Quoted 8 lines

git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-use-css-ref

diffstat follows. Thanks.

 include/linux/cgroup.h |   25 ----
 kernel/cgroup.c        |  284 ++++++++++++++++++++++---------------------------
 2 files changed, 136 insertions(+), 173 deletions(-)

With the memory leak fixed:

author maintainer Applied
#22 lore raw
In reply to Tejun Heo
Quoted 26 lines · Tejun Heo

Hello,

Currently, cgroup and css (cgroup_subsys_state) are separately reference counted. cgroup->refcnt is an atomic_t and css->refcnt is a percpu_ref. css is becoming the primary structural block and used widely in various operaitons. cgroup already has a css embedded in it (cgroup->dummy_css) to use as its proxy in such operations; however, there still are quite a few differences between cgroup and css handling limitng how cgroup->dummy_css can be used.

This patchset makes cgroup use the embedded css's refcnt for reference counting. This closes one of the gaps between an cgroup embedded css, which is renamed to cgroup->self early in the patchset, and a normal css and will allow more unified handling of cgroups and csses. In addition, this makes cgroup refcnting use percpu_ref too, which is a lot more scalable than an atomic_t.

Ultimately, it'd make things far simpler to assign a proper cgroup_subsys to the cgroup embedded csses and handle them the same as other csses; however, we can't yet do it thanks to multiple hierarchies as we end up with multiple csses of the same subsystem for the same task, but in the very long term, if multiple hierarchies can be removed, that's where it's headed.

This patchset contains the following nine patches.

Quoted 9 lines

0001-cgroup-use-restart_syscall-for-mount-retries.patch 0002-cgroup-rename-cgroup-dummy_css-to-self-and-move-it-t.patch 0003-cgroup-separate-out-cgroup_has_live_children-from-cg.patch 0004-cgroup-move-check_for_release-parent-call-to-the-end.patch 0005-cgroup-move-cgroup-sibling-unlinking-to-cgroup_put.patch 0006-cgroup-remove-cgroup_destory_css_killed.patch 0007-cgroup-bounce-css-release-through-css-destroy_work.patch 0008-cgroup-enable-refcnting-for-root-csses.patch 0009-cgroup-use-cgroup-self.refcnt-for-cgroup-refcnting.patch

Applied to cgroup/for-3.16.

Thanks.

Signature · 1 line
tejun