cgroup: Clean up css_set task traversal

css_task_iter stores pointer to head of each iterable list, this dates
back to commit 0f0a2b4fa6 ("cgroup: reorganize css_task_iter") when we
did not store cur_cset. Let us utilize list heads directly in cur_cset
and streamline css_task_iter_advance_css_set a bit. This is no
intentional function change.

Signed-off-by: Michal Koutný <mkoutny@suse.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
Michal Koutný 2020-01-24 12:40:16 +01:00 committed by Tejun Heo
parent 9c974c7724
commit f43caa2adc
2 changed files with 28 additions and 36 deletions

View File

@ -58,9 +58,6 @@ struct css_task_iter {
struct list_head *tcset_head;
struct list_head *task_pos;
struct list_head *tasks_head;
struct list_head *mg_tasks_head;
struct list_head *dying_tasks_head;
struct list_head *cur_tasks_head;
struct css_set *cur_cset;

View File

@ -4391,29 +4391,24 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it)
lockdep_assert_held(&css_set_lock);
/* Advance to the next non-empty css_set */
do {
cset = css_task_iter_next_css_set(it);
if (!cset) {
it->task_pos = NULL;
return;
/* Advance to the next non-empty css_set and find first non-empty tasks list*/
while ((cset = css_task_iter_next_css_set(it))) {
if (!list_empty(&cset->tasks)) {
it->cur_tasks_head = &cset->tasks;
break;
} else if (!list_empty(&cset->mg_tasks)) {
it->cur_tasks_head = &cset->mg_tasks;
break;
} else if (!list_empty(&cset->dying_tasks)) {
it->cur_tasks_head = &cset->dying_tasks;
break;
}
} while (!css_set_populated(cset) && list_empty(&cset->dying_tasks));
if (!list_empty(&cset->tasks)) {
it->task_pos = cset->tasks.next;
it->cur_tasks_head = &cset->tasks;
} else if (!list_empty(&cset->mg_tasks)) {
it->task_pos = cset->mg_tasks.next;
it->cur_tasks_head = &cset->mg_tasks;
} else {
it->task_pos = cset->dying_tasks.next;
it->cur_tasks_head = &cset->dying_tasks;
}
it->tasks_head = &cset->tasks;
it->mg_tasks_head = &cset->mg_tasks;
it->dying_tasks_head = &cset->dying_tasks;
if (!cset) {
it->task_pos = NULL;
return;
}
it->task_pos = it->cur_tasks_head->next;
/*
* We don't keep css_sets locked across iteration steps and thus
@ -4458,24 +4453,24 @@ static void css_task_iter_advance(struct css_task_iter *it)
repeat:
if (it->task_pos) {
/*
* Advance iterator to find next entry. cset->tasks is
* consumed first and then ->mg_tasks. After ->mg_tasks,
* we move onto the next cset.
* Advance iterator to find next entry. We go through cset
* tasks, mg_tasks and dying_tasks, when consumed we move onto
* the next cset.
*/
if (it->flags & CSS_TASK_ITER_SKIPPED)
it->flags &= ~CSS_TASK_ITER_SKIPPED;
else
it->task_pos = it->task_pos->next;
if (it->task_pos == it->tasks_head) {
it->task_pos = it->mg_tasks_head->next;
it->cur_tasks_head = it->mg_tasks_head;
if (it->task_pos == &it->cur_cset->tasks) {
it->cur_tasks_head = &it->cur_cset->mg_tasks;
it->task_pos = it->cur_tasks_head->next;
}
if (it->task_pos == it->mg_tasks_head) {
it->task_pos = it->dying_tasks_head->next;
it->cur_tasks_head = it->dying_tasks_head;
if (it->task_pos == &it->cur_cset->mg_tasks) {
it->cur_tasks_head = &it->cur_cset->dying_tasks;
it->task_pos = it->cur_tasks_head->next;
}
if (it->task_pos == it->dying_tasks_head)
if (it->task_pos == &it->cur_cset->dying_tasks)
css_task_iter_advance_css_set(it);
} else {
/* called from start, proceed to the first cset */
@ -4493,12 +4488,12 @@ static void css_task_iter_advance(struct css_task_iter *it)
goto repeat;
/* and dying leaders w/o live member threads */
if (it->cur_tasks_head == it->dying_tasks_head &&
if (it->cur_tasks_head == &it->cur_cset->dying_tasks &&
!atomic_read(&task->signal->live))
goto repeat;
} else {
/* skip all dying ones */
if (it->cur_tasks_head == it->dying_tasks_head)
if (it->cur_tasks_head == &it->cur_cset->dying_tasks)
goto repeat;
}
}