Commit 0f0a2b4f authored by Tejun Heo's avatar Tejun Heo

cgroup: reorganize css_task_iter

This patch reorganizes css_task_iter so that adding effective css
support is easier.

* s/->cset_link/->cset_pos/ and s/->task/->task_pos/ for consistency

* ->origin_css is used to determine whether the iteration reached the
  last css_set.  Replace it with explicit ->cset_head so that
  css_advance_task_iter() doesn't have to know the termination
  condition directly.

* css_task_iter_next() currently assumes that it's walking list of
  cgrp_cset_link and reaches into the current cset through the current
  link to determine the termination conditions for task walking.  As
  this won't always be true for effective css walking, add
  ->tasks_head and ->mg_tasks_head and use them to control task
  walking so that css_task_iter_next() doesn't have to know how
  css_sets are being walked.

This patch doesn't make any behavior changes.  The iteration logic
stays unchanged after the patch.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarLi Zefan <lizefan@huawei.com>
parent 3b281afb
...@@ -842,9 +842,12 @@ css_next_descendant_post(struct cgroup_subsys_state *pos, ...@@ -842,9 +842,12 @@ css_next_descendant_post(struct cgroup_subsys_state *pos,
/* A css_task_iter should be treated as an opaque object */ /* A css_task_iter should be treated as an opaque object */
struct css_task_iter { struct css_task_iter {
struct cgroup_subsys_state *origin_css; struct list_head *cset_pos;
struct list_head *cset_link; struct list_head *cset_head;
struct list_head *task;
struct list_head *task_pos;
struct list_head *tasks_head;
struct list_head *mg_tasks_head;
}; };
void css_task_iter_start(struct cgroup_subsys_state *css, void css_task_iter_start(struct cgroup_subsys_state *css,
......
...@@ -2857,27 +2857,30 @@ css_next_descendant_post(struct cgroup_subsys_state *pos, ...@@ -2857,27 +2857,30 @@ css_next_descendant_post(struct cgroup_subsys_state *pos,
*/ */
static void css_advance_task_iter(struct css_task_iter *it) static void css_advance_task_iter(struct css_task_iter *it)
{ {
struct list_head *l = it->cset_link; struct list_head *l = it->cset_pos;
struct cgrp_cset_link *link; struct cgrp_cset_link *link;
struct css_set *cset; struct css_set *cset;
/* Advance to the next non-empty css_set */ /* Advance to the next non-empty css_set */
do { do {
l = l->next; l = l->next;
if (l == &it->origin_css->cgroup->cset_links) { if (l == it->cset_head) {
it->cset_link = NULL; it->cset_pos = NULL;
return; return;
} }
link = list_entry(l, struct cgrp_cset_link, cset_link); link = list_entry(l, struct cgrp_cset_link, cset_link);
cset = link->cset; cset = link->cset;
} while (list_empty(&cset->tasks) && list_empty(&cset->mg_tasks)); } while (list_empty(&cset->tasks) && list_empty(&cset->mg_tasks));
it->cset_link = l; it->cset_pos = l;
if (!list_empty(&cset->tasks)) if (!list_empty(&cset->tasks))
it->task = cset->tasks.next; it->task_pos = cset->tasks.next;
else else
it->task = cset->mg_tasks.next; it->task_pos = cset->mg_tasks.next;
it->tasks_head = &cset->tasks;
it->mg_tasks_head = &cset->mg_tasks;
} }
/** /**
...@@ -2903,8 +2906,8 @@ void css_task_iter_start(struct cgroup_subsys_state *css, ...@@ -2903,8 +2906,8 @@ void css_task_iter_start(struct cgroup_subsys_state *css,
down_read(&css_set_rwsem); down_read(&css_set_rwsem);
it->origin_css = css; it->cset_pos = &css->cgroup->cset_links;
it->cset_link = &css->cgroup->cset_links; it->cset_head = it->cset_pos;
css_advance_task_iter(it); css_advance_task_iter(it);
} }
...@@ -2920,12 +2923,10 @@ void css_task_iter_start(struct cgroup_subsys_state *css, ...@@ -2920,12 +2923,10 @@ void css_task_iter_start(struct cgroup_subsys_state *css,
struct task_struct *css_task_iter_next(struct css_task_iter *it) struct task_struct *css_task_iter_next(struct css_task_iter *it)
{ {
struct task_struct *res; struct task_struct *res;
struct list_head *l = it->task; struct list_head *l = it->task_pos;
struct cgrp_cset_link *link = list_entry(it->cset_link,
struct cgrp_cset_link, cset_link);
/* If the iterator cg is NULL, we have no tasks */ /* If the iterator cg is NULL, we have no tasks */
if (!it->cset_link) if (!it->cset_pos)
return NULL; return NULL;
res = list_entry(l, struct task_struct, cg_list); res = list_entry(l, struct task_struct, cg_list);
...@@ -2936,13 +2937,13 @@ struct task_struct *css_task_iter_next(struct css_task_iter *it) ...@@ -2936,13 +2937,13 @@ struct task_struct *css_task_iter_next(struct css_task_iter *it)
*/ */
l = l->next; l = l->next;
if (l == &link->cset->tasks) if (l == it->tasks_head)
l = link->cset->mg_tasks.next; l = it->mg_tasks_head->next;
if (l == &link->cset->mg_tasks) if (l == it->mg_tasks_head)
css_advance_task_iter(it); css_advance_task_iter(it);
else else
it->task = l; it->task_pos = l;
return res; return res;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment