浏览代码

cgroup: implement cgroup_rightmost_descendant()

Implement cgroup_rightmost_descendant() which returns the right most
descendant of the specified cgroup.  This can be used to skip the
cgroup's subtree while iterating with
cgroup_for_each_descendant_pre().

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Michal Hocko <mhocko@suse.cz>
Acked-by: Li Zefan <lizefan@huawei.com>
Tejun Heo 12 年之前
父节点
当前提交
12a9d2fef1
共有 2 个文件被更改,包括 27 次插入0 次删除
  1. 1 0
      include/linux/cgroup.h
  2. 26 0
      kernel/cgroup.c

+ 1 - 0
include/linux/cgroup.h

@@ -558,6 +558,7 @@ static inline struct cgroup* task_cgroup(struct task_struct *task,
 
 
 struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
 struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
 					  struct cgroup *cgroup);
 					  struct cgroup *cgroup);
+struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos);
 
 
 /**
 /**
  * cgroup_for_each_descendant_pre - pre-order walk of a cgroup's descendants
  * cgroup_for_each_descendant_pre - pre-order walk of a cgroup's descendants

+ 26 - 0
kernel/cgroup.c

@@ -3017,6 +3017,32 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
 }
 }
 EXPORT_SYMBOL_GPL(cgroup_next_descendant_pre);
 EXPORT_SYMBOL_GPL(cgroup_next_descendant_pre);
 
 
+/**
+ * cgroup_rightmost_descendant - return the rightmost descendant of a cgroup
+ * @pos: cgroup of interest
+ *
+ * Return the rightmost descendant of @pos.  If there's no descendant,
+ * @pos is returned.  This can be used during pre-order traversal to skip
+ * subtree of @pos.
+ */
+struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos)
+{
+	struct cgroup *last, *tmp;
+
+	WARN_ON_ONCE(!rcu_read_lock_held());
+
+	do {
+		last = pos;
+		/* ->prev isn't RCU safe, walk ->next till the end */
+		pos = NULL;
+		list_for_each_entry_rcu(tmp, &last->children, sibling)
+			pos = tmp;
+	} while (pos);
+
+	return last;
+}
+EXPORT_SYMBOL_GPL(cgroup_rightmost_descendant);
+
 static struct cgroup *cgroup_leftmost_descendant(struct cgroup *pos)
 static struct cgroup *cgroup_leftmost_descendant(struct cgroup *pos)
 {
 {
 	struct cgroup *last;
 	struct cgroup *last;