diff options
-rw-r--r-- | include/linux/cgroup.h | 1 | ||||
-rw-r--r-- | kernel/cgroup.c | 26 |
2 files changed, 27 insertions, 0 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 942e68705577..8118a3120378 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -558,6 +558,7 @@ static inline struct cgroup* task_cgroup(struct task_struct *task, | |||
558 | 558 | ||
559 | struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos, | 559 | struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos, |
560 | struct cgroup *cgroup); | 560 | struct cgroup *cgroup); |
561 | struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos); | ||
561 | 562 | ||
562 | /** | 563 | /** |
563 | * cgroup_for_each_descendant_pre - pre-order walk of a cgroup's descendants | 564 | * cgroup_for_each_descendant_pre - pre-order walk of a cgroup's descendants |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 4855892798fd..6643f7053454 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -3017,6 +3017,32 @@ struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos, | |||
3017 | } | 3017 | } |
3018 | EXPORT_SYMBOL_GPL(cgroup_next_descendant_pre); | 3018 | EXPORT_SYMBOL_GPL(cgroup_next_descendant_pre); |
3019 | 3019 | ||
3020 | /** | ||
3021 | * cgroup_rightmost_descendant - return the rightmost descendant of a cgroup | ||
3022 | * @pos: cgroup of interest | ||
3023 | * | ||
3024 | * Return the rightmost descendant of @pos. If there's no descendant, | ||
3025 | * @pos is returned. This can be used during pre-order traversal to skip | ||
3026 | * subtree of @pos. | ||
3027 | */ | ||
3028 | struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos) | ||
3029 | { | ||
3030 | struct cgroup *last, *tmp; | ||
3031 | |||
3032 | WARN_ON_ONCE(!rcu_read_lock_held()); | ||
3033 | |||
3034 | do { | ||
3035 | last = pos; | ||
3036 | /* ->prev isn't RCU safe, walk ->next till the end */ | ||
3037 | pos = NULL; | ||
3038 | list_for_each_entry_rcu(tmp, &last->children, sibling) | ||
3039 | pos = tmp; | ||
3040 | } while (pos); | ||
3041 | |||
3042 | return last; | ||
3043 | } | ||
3044 | EXPORT_SYMBOL_GPL(cgroup_rightmost_descendant); | ||
3045 | |||
3020 | static struct cgroup *cgroup_leftmost_descendant(struct cgroup *pos) | 3046 | static struct cgroup *cgroup_leftmost_descendant(struct cgroup *pos) |
3021 | { | 3047 | { |
3022 | struct cgroup *last; | 3048 | struct cgroup *last; |