cgroup: reorganize css_task_iter functions

* Rename css_advance_task_iter() to css_task_iter_advance_css_set()
  and make it clear it->task_pos too at the end of the iteration.

* Factor out css_task_iter_advance() from css_task_iter_next().  The
  new function whines if called on a terminated iterator.

Except for the termination check, this is pure reorganization and
doesn't introduce any behavior changes.  This will help the planned
locking update for css_task_iter.

Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
Tejun Heo 2015-10-15 16:41:52 -04:00
Родитель f6d7d049c1
Коммит ecb9d535df
1 изменённых файлов: 28 добавлений и 21 удалений

Просмотреть файл

@ -3793,12 +3793,12 @@ bool css_has_online_children(struct cgroup_subsys_state *css)
} }
/** /**
* css_advance_task_iter - advance a task itererator to the next css_set * css_task_iter_advance_css_set - advance a task itererator to the next css_set
* @it: the iterator to advance * @it: the iterator to advance
* *
* Advance @it to the next css_set to walk. * Advance @it to the next css_set to walk.
*/ */
static void css_advance_task_iter(struct css_task_iter *it) static void css_task_iter_advance_css_set(struct css_task_iter *it)
{ {
struct list_head *l = it->cset_pos; struct list_head *l = it->cset_pos;
struct cgrp_cset_link *link; struct cgrp_cset_link *link;
@ -3809,6 +3809,7 @@ static void css_advance_task_iter(struct css_task_iter *it)
l = l->next; l = l->next;
if (l == it->cset_head) { if (l == it->cset_head) {
it->cset_pos = NULL; it->cset_pos = NULL;
it->task_pos = NULL;
return; return;
} }
@ -3832,6 +3833,28 @@ static void css_advance_task_iter(struct css_task_iter *it)
it->mg_tasks_head = &cset->mg_tasks; it->mg_tasks_head = &cset->mg_tasks;
} }
static void css_task_iter_advance(struct css_task_iter *it)
{
struct list_head *l = it->task_pos;
WARN_ON_ONCE(!l);
/*
* Advance iterator to find next entry. cset->tasks is consumed
* first and then ->mg_tasks. After ->mg_tasks, we move onto the
* next cset.
*/
l = l->next;
if (l == it->tasks_head)
l = it->mg_tasks_head->next;
if (l == it->mg_tasks_head)
css_task_iter_advance_css_set(it);
else
it->task_pos = l;
}
/** /**
* css_task_iter_start - initiate task iteration * css_task_iter_start - initiate task iteration
* @css: the css to walk tasks of * @css: the css to walk tasks of
@ -3864,7 +3887,7 @@ void css_task_iter_start(struct cgroup_subsys_state *css,
it->cset_head = it->cset_pos; it->cset_head = it->cset_pos;
css_advance_task_iter(it); css_task_iter_advance_css_set(it);
} }
/** /**
@ -3878,28 +3901,12 @@ 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_pos;
/* If the iterator cg is NULL, we have no tasks */
if (!it->cset_pos) if (!it->cset_pos)
return NULL; return NULL;
res = list_entry(l, struct task_struct, cg_list);
/*
* Advance iterator to find next entry. cset->tasks is consumed
* first and then ->mg_tasks. After ->mg_tasks, we move onto the
* next cset.
*/
l = l->next;
if (l == it->tasks_head)
l = it->mg_tasks_head->next;
if (l == it->mg_tasks_head)
css_advance_task_iter(it);
else
it->task_pos = l;
res = list_entry(it->task_pos, struct task_struct, cg_list);
css_task_iter_advance(it);
return res; return res;
} }