aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/cgroup.h
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-11-09 12:12:29 -0500
committerTejun Heo <tj@kernel.org>2012-11-09 12:12:29 -0500
commit574bd9f7c7c1d32f52dea5488018a6ff79031e22 (patch)
treef43657afb59dd12fe1eca329acc6caf885507727 /include/linux/cgroup.h
parenteb6fd5040ee799009173daa49c3e7aa0362167c9 (diff)
cgroup: implement generic child / descendant walk macros
Currently, cgroup doesn't provide any generic helper for walking a given cgroup's children or descendants. This patch adds the following three macros. * cgroup_for_each_child() - walk immediate children of a cgroup. * cgroup_for_each_descendant_pre() - visit all descendants of a cgroup in pre-order tree traversal. * cgroup_for_each_descendant_post() - visit all descendants of a cgroup in post-order tree traversal. All three only require the user to hold RCU read lock during traversal. Verifying that each iterated cgroup is online is the responsibility of the user. When used with proper synchronization, cgroup_for_each_descendant_pre() can be used to propagate state updates to descendants in reliable way. See comments for details. v2: s/config/state/ in commit message and comments per Michal. More documentation on synchronization rules. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujisu.com> Reviewed-by: Michal Hocko <mhocko@suse.cz> Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'include/linux/cgroup.h')
-rw-r--r--include/linux/cgroup.h94
1 files changed, 94 insertions, 0 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 90c33ebdd6bc..8f64b459fbd4 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -534,6 +534,100 @@ static inline struct cgroup* task_cgroup(struct task_struct *task,
534 return task_subsys_state(task, subsys_id)->cgroup; 534 return task_subsys_state(task, subsys_id)->cgroup;
535} 535}
536 536
537/**
538 * cgroup_for_each_child - iterate through children of a cgroup
539 * @pos: the cgroup * to use as the loop cursor
540 * @cgroup: cgroup whose children to walk
541 *
542 * Walk @cgroup's children. Must be called under rcu_read_lock(). A child
543 * cgroup which hasn't finished ->post_create() or already has finished
544 * ->pre_destroy() may show up during traversal and it's each subsystem's
545 * responsibility to verify that each @pos is alive.
546 *
547 * If a subsystem synchronizes against the parent in its ->post_create()
548 * and before starting iterating, a cgroup which finished ->post_create()
549 * is guaranteed to be visible in the future iterations.
550 */
551#define cgroup_for_each_child(pos, cgroup) \
552 list_for_each_entry_rcu(pos, &(cgroup)->children, sibling)
553
554struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos,
555 struct cgroup *cgroup);
556
557/**
558 * cgroup_for_each_descendant_pre - pre-order walk of a cgroup's descendants
559 * @pos: the cgroup * to use as the loop cursor
560 * @cgroup: cgroup whose descendants to walk
561 *
562 * Walk @cgroup's descendants. Must be called under rcu_read_lock(). A
563 * descendant cgroup which hasn't finished ->post_create() or already has
564 * finished ->pre_destroy() may show up during traversal and it's each
565 * subsystem's responsibility to verify that each @pos is alive.
566 *
567 * If a subsystem synchronizes against the parent in its ->post_create()
568 * and before starting iterating, and synchronizes against @pos on each
569 * iteration, any descendant cgroup which finished ->post_create() is
570 * guaranteed to be visible in the future iterations.
571 *
572 * In other words, the following guarantees that a descendant can't escape
573 * state updates of its ancestors.
574 *
575 * my_post_create(@cgrp)
576 * {
577 * Lock @cgrp->parent and @cgrp;
578 * Inherit state from @cgrp->parent;
579 * Unlock both.
580 * }
581 *
582 * my_update_state(@cgrp)
583 * {
584 * Lock @cgrp;
585 * Update @cgrp's state;
586 * Unlock @cgrp;
587 *
588 * cgroup_for_each_descendant_pre(@pos, @cgrp) {
589 * Lock @pos;
590 * Verify @pos is alive and inherit state from @pos->parent;
591 * Unlock @pos;
592 * }
593 * }
594 *
595 * As long as the inheriting step, including checking the parent state, is
596 * enclosed inside @pos locking, double-locking the parent isn't necessary
597 * while inheriting. The state update to the parent is guaranteed to be
598 * visible by walking order and, as long as inheriting operations to the
599 * same @pos are atomic to each other, multiple updates racing each other
600 * still result in the correct state. It's guaranateed that at least one
601 * inheritance happens for any cgroup after the latest update to its
602 * parent.
603 *
604 * If checking parent's state requires locking the parent, each inheriting
605 * iteration should lock and unlock both @pos->parent and @pos.
606 *
607 * Alternatively, a subsystem may choose to use a single global lock to
608 * synchronize ->post_create() and ->pre_destroy() against tree-walking
609 * operations.
610 */
611#define cgroup_for_each_descendant_pre(pos, cgroup) \
612 for (pos = cgroup_next_descendant_pre(NULL, (cgroup)); (pos); \
613 pos = cgroup_next_descendant_pre((pos), (cgroup)))
614
615struct cgroup *cgroup_next_descendant_post(struct cgroup *pos,
616 struct cgroup *cgroup);
617
618/**
619 * cgroup_for_each_descendant_post - post-order walk of a cgroup's descendants
620 * @pos: the cgroup * to use as the loop cursor
621 * @cgroup: cgroup whose descendants to walk
622 *
623 * Similar to cgroup_for_each_descendant_pre() but performs post-order
624 * traversal instead. Note that the walk visibility guarantee described in
625 * pre-order walk doesn't apply the same to post-order walks.
626 */
627#define cgroup_for_each_descendant_post(pos, cgroup) \
628 for (pos = cgroup_next_descendant_post(NULL, (cgroup)); (pos); \
629 pos = cgroup_next_descendant_post((pos), (cgroup)))
630
537/* A cgroup_iter should be treated as an opaque object */ 631/* A cgroup_iter should be treated as an opaque object */
538struct cgroup_iter { 632struct cgroup_iter {
539 struct list_head *cg_link; 633 struct list_head *cg_link;