public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: lizefan@huawei.com
Cc: containers@lists.linux-foundation.org, cgroups@vger.kernel.org,
	linux-kernel@vger.kernel.org, Tejun Heo <tj@kernel.org>
Subject: [PATCH 13/23] cgroup: convert cgroup_next_sibling() to cgroup_next_child()
Date: Thu,  1 Aug 2013 17:49:51 -0400	[thread overview]
Message-ID: <1375393801-4817-14-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1375393801-4817-1-git-send-email-tj@kernel.org>

cgroup is transitioning to using css (cgroup_subsys_state) as the main
subsys interface handle instead of cgroup and the iterators will be
updated to use css too.  The iterators need to walk the cgroup
hierarchy and return the css's matching the origin css, which is a bit
cumbersome to open code.

This patch converts cgroup_next_sibling() to cgroup_next_child() so
that it can handle all steps of direct child iteration.  This will be
used to update iterators to take @css instead of @cgrp.  In addition
to the new iteration init handling, cgroup_next_child() is
restructured so that the different branches share the end of iteration
condition check.

This patch doesn't change any behavior.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 include/linux/cgroup.h |  4 ++--
 kernel/cgroup.c        | 59 +++++++++++++++++++++++++-------------------------
 2 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 9749d63..a91c304 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -780,7 +780,7 @@ static inline struct cgroup *cgroup_from_id(struct cgroup_subsys *ss, int id)
 	return idr_find(&ss->root->cgroup_idr, id);
 }
 
-struct cgroup *cgroup_next_sibling(struct cgroup *pos);
+struct cgroup *cgroup_next_child(struct cgroup *pos, struct cgroup *cgrp);
 
 /**
  * cgroup_for_each_child - iterate through children of a cgroup
@@ -803,7 +803,7 @@ struct cgroup *cgroup_next_sibling(struct cgroup *pos);
 #define cgroup_for_each_child(pos, cgrp)				\
 	for ((pos) = list_first_or_null_rcu(&(cgrp)->children,		\
 					    struct cgroup, sibling);	\
-	     (pos); (pos) = cgroup_next_sibling((pos)))
+	     (pos); (pos) = cgroup_next_child((pos), (cgrp)))
 
 struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
 					  struct cgroup *cgroup);
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 6c68192..e88b50e 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -3030,15 +3030,16 @@ static void cgroup_enable_task_cg_lists(void)
 }
 
 /**
- * cgroup_next_sibling - find the next sibling of a given cgroup
- * @pos: the current cgroup
+ * cgroup_next_child - find the next child of a given cgroup
+ * @pos: the current position (%NULL to initiate traversal)
+ * @cgrp: cgroup whose descendants to walk
  *
- * This function returns the next sibling of @pos and should be called
- * under RCU read lock.  The only requirement is that @pos is accessible.
- * The next sibling is guaranteed to be returned regardless of @pos's
- * state.
+ * This function returns the next child of @cgrp and should be called under
+ * RCU read lock.  The only requirement is that @cgrp and @pos are
+ * accessible.  The next sibling is guaranteed to be returned regardless of
+ * their states.
  */
-struct cgroup *cgroup_next_sibling(struct cgroup *pos)
+struct cgroup *cgroup_next_child(struct cgroup *pos, struct cgroup *cgrp)
 {
 	struct cgroup *next;
 
@@ -3054,30 +3055,30 @@ struct cgroup *cgroup_next_sibling(struct cgroup *pos)
 	 * safe to dereference from this RCU critical section.  If
 	 * ->sibling.next is inaccessible, cgroup_is_dead() is guaranteed
 	 * to be visible as %true here.
+	 *
+	 * If @pos is dead, its next pointer can't be dereferenced;
+	 * however, as each cgroup is given a monotonically increasing
+	 * unique serial number and always appended to the sibling list,
+	 * the next one can be found by walking the parent's children until
+	 * we see a cgroup with higher serial number than @pos's.  While
+	 * this path can be slower, it's taken only when either the current
+	 * cgroup is removed or iteration and removal race.
 	 */
-	if (likely(!cgroup_is_dead(pos))) {
+	if (!pos) {
+		next = list_entry_rcu(cgrp->children.next, struct cgroup, sibling);
+	} else if (likely(!cgroup_is_dead(pos))) {
 		next = list_entry_rcu(pos->sibling.next, struct cgroup, sibling);
-		if (&next->sibling != &pos->parent->children)
-			return next;
-		return NULL;
+	} else {
+		list_for_each_entry_rcu(next, &cgrp->children, sibling)
+			if (next->serial_nr > pos->serial_nr)
+				break;
 	}
 
-	/*
-	 * Can't dereference the next pointer.  Each cgroup is given a
-	 * monotonically increasing unique serial number and always
-	 * appended to the sibling list, so the next one can be found by
-	 * walking the parent's children until we see a cgroup with higher
-	 * serial number than @pos's.
-	 *
-	 * While this path can be slow, it's taken only when either the
-	 * current cgroup is removed or iteration and removal race.
-	 */
-	list_for_each_entry_rcu(next, &pos->parent->children, sibling)
-		if (next->serial_nr > pos->serial_nr)
-			return next;
+	if (&next->sibling != &cgrp->children)
+		return next;
 	return NULL;
 }
-EXPORT_SYMBOL_GPL(cgroup_next_sibling);
+EXPORT_SYMBOL_GPL(cgroup_next_child);
 
 /**
  * cgroup_next_descendant_pre - find the next descendant for pre-order walk
@@ -3110,7 +3111,7 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
 
 	/* no child, visit my or the closest ancestor's next sibling */
 	while (pos != cgroup) {
-		next = cgroup_next_sibling(pos);
+		next = cgroup_next_child(pos, pos->parent);
 		if (next)
 			return next;
 		pos = pos->parent;
@@ -3191,7 +3192,7 @@ struct cgroup *cgroup_next_descendant_post(struct cgroup *pos,
 	}
 
 	/* if there's an unvisited sibling, visit its leftmost descendant */
-	next = cgroup_next_sibling(pos);
+	next = cgroup_next_child(pos, pos->parent);
 	if (next)
 		return cgroup_leftmost_descendant(next);
 
@@ -4540,9 +4541,9 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
 	/*
 	 * Mark @cgrp dead.  This prevents further task migration and child
 	 * creation by disabling cgroup_lock_live_group().  Note that
-	 * CGRP_DEAD assertion is depended upon by cgroup_next_sibling() to
+	 * CGRP_DEAD assertion is depended upon by cgroup_next_child() to
 	 * resume iteration after dropping RCU read lock.  See
-	 * cgroup_next_sibling() for details.
+	 * cgroup_next_child() for details.
 	 */
 	set_bit(CGRP_DEAD, &cgrp->flags);
 
-- 
1.8.3.1


  parent reply	other threads:[~2013-08-01 21:54 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-01 21:49 [PATCHSET cgroup/for-3.12] cgroup: use cgroup_subsys_state as the primary subsystem interface handle Tejun Heo
2013-08-01 21:49 ` [PATCH 01/23] cgroup: s/cgroup_subsys_state/cgroup_css/ s/task_subsys_state/task_css/ Tejun Heo
2013-08-01 21:49 ` [PATCH 02/23] cpuset: drop "const" qualifiers from struct cpuset instances Tejun Heo
2013-08-01 21:49 ` [PATCH 03/23] netprio_cgroup: pass around @css instead of @cgroup and kill struct cgroup_netprio_state Tejun Heo
2013-08-01 22:07   ` David Miller
2013-08-02 11:42   ` Neil Horman
2013-08-01 21:49 ` [PATCH 04/23] hugetlb_cgroup: pass around @hugetlb_cgroup instead of @cgroup Tejun Heo
2013-08-02  4:35   ` Aneesh Kumar K.V
2013-08-02 13:10   ` Michal Hocko
2013-08-01 21:49 ` [PATCH 05/23] cgroup: add subsystem pointer to cgroup_subsys_state Tejun Heo
2013-08-01 21:49 ` [PATCH 06/23] cgroup: add/update accessors which obtain subsys specific data from css Tejun Heo
2013-08-01 21:49 ` [PATCH 07/23] cgroup: add css_parent() Tejun Heo
2013-08-01 21:49 ` [PATCH 08/23] cgroup: pass around cgroup_subsys_state instead of cgroup in subsystem methods Tejun Heo
2013-08-02  3:54   ` Li Zefan
2013-08-02 19:36     ` Tejun Heo
2013-08-02  4:02   ` Li Zefan
2013-08-02 19:41     ` Tejun Heo
2013-08-02 13:19   ` Michal Hocko
2013-08-02 13:43     ` Michal Hocko
2013-08-02 19:52       ` Tejun Heo
2013-08-02 19:38     ` Tejun Heo
2013-08-02 20:24   ` [PATCH v2 " Tejun Heo
2013-08-06  7:19     ` Daniel Wagner
2013-08-05 12:44   ` [PATCH " Vivek Goyal
2013-08-05 17:57   ` Aristeu Rozanski
2013-08-01 21:49 ` [PATCH 09/23] cgroup: add subsys backlink pointer to cftype Tejun Heo
2013-08-05 12:49   ` Vivek Goyal
2013-08-01 21:49 ` [PATCH 10/23] cgroup: pin cgroup_subsys_state when opening a cgroupfs file Tejun Heo
2013-08-01 21:49 ` [PATCH 11/23] cgroup: add cgroup->dummy_css Tejun Heo
2013-08-01 21:49 ` [PATCH 12/23] cgroup: pass around cgroup_subsys_state instead of cgroup in file methods Tejun Heo
2013-08-02 13:27   ` Michal Hocko
2013-08-05 14:19   ` Vivek Goyal
2013-08-05 18:04   ` Aristeu Rozanski
2013-08-06  6:48   ` Daniel Wagner
2013-08-01 21:49 ` Tejun Heo [this message]
2013-08-01 21:49 ` [PATCH 14/23] cgroup: always use cgroup_next_child() to walk the children list Tejun Heo
2013-08-01 21:49 ` [PATCH 15/23] cgroup: make hierarchy iterators deal with cgroup_subsys_state instead of cgroup Tejun Heo
2013-08-02 13:32   ` Michal Hocko
2013-08-05 14:25   ` Vivek Goyal
2013-08-05 18:10   ` Aristeu Rozanski
2013-08-01 21:49 ` [PATCH 16/23] cgroup: relocate cgroup_advance_iter() Tejun Heo
2013-08-02  3:25   ` Li Zefan
2013-08-02 19:35     ` Tejun Heo
2013-08-01 21:49 ` [PATCH 17/23] cgroup: rename cgroup_iter to cgroup_task_iter Tejun Heo
2013-08-02 13:35   ` Michal Hocko
2013-08-01 21:49 ` [PATCH 18/23] cgroup: make cgroup_task_iter remember the cgroup being iterated Tejun Heo
2013-08-02 13:38   ` Michal Hocko
2013-08-01 21:49 ` [PATCH 19/23] cgroup: remove struct cgroup_scanner Tejun Heo
2013-08-01 21:49 ` [PATCH 20/23] cgroup: make task iterators deal with cgroup_subsys_state instead of cgroup Tejun Heo
2013-08-02 13:40   ` Michal Hocko
2013-08-01 21:49 ` [PATCH 21/23] cgroup: make cftype->[un]register_event() " Tejun Heo
2013-08-02  4:08   ` Li Zefan
2013-08-02 19:44     ` Tejun Heo
2013-08-02 13:42   ` Michal Hocko
2013-08-02 20:24   ` [PATCH v2 " Tejun Heo
2013-08-01 21:50 ` [PATCH 22/23] cgroup: make cgroup_taskset " Tejun Heo
2013-08-06  6:53   ` Daniel Wagner
2013-08-01 21:50 ` [PATCH 23/23] cgroup: unexport cgroup_css() Tejun Heo
2013-08-02  3:24 ` [PATCHSET cgroup/for-3.12] cgroup: use cgroup_subsys_state as the primary subsystem interface handle Li Zefan
2013-08-09  0:12 ` Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1375393801-4817-14-git-send-email-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=cgroups@vger.kernel.org \
    --cc=containers@lists.linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox