css_task_iter stores pointer to head of each iterable list, this dates back to commit 0f0a2b4fa621 ("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.
Showing the changes to kernel/cgroup (1 of 2 files). Show all
Unified · Split
| @@ -4391,29 +4391,24 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it) · 4390 unmodified lines | ||
| 4391 | 4391 | |
| 4392 | 4392 | lockdep_assert_held(&css_set_lock); |
| 4393 | 4393 | |
| 4394 | − /* Advance to the next non-empty css_set */ | |
| 4395 | − do { | |
| 4396 | − cset = css_task_iter_next_css_set(it); | |
| 4397 | − if (!cset) { | |
| 4398 | − it->task_pos = NULL; | |
| 4399 | − return; | |
| 4394 | + /* Advance to the next non-empty css_set and find first non-empty tasks list*/ | |
| 4395 | + while ((cset = css_task_iter_next_css_set(it))) { | |
| 4396 | + if (!list_empty(&cset->tasks)) { | |
| 4397 | + it->cur_tasks_head = &cset->tasks; | |
| 4398 | + break; | |
| 4399 | + } else if (!list_empty(&cset->mg_tasks)) { | |
| 4400 | + it->cur_tasks_head = &cset->mg_tasks; | |
| 4401 | + break; | |
| 4402 | + } else if (!list_empty(&cset->dying_tasks)) { | |
| 4403 | + it->cur_tasks_head = &cset->dying_tasks; | |
| 4404 | + break; | |
| 4400 | 4405 | } |
| 4401 | − } while (!css_set_populated(cset) && list_empty(&cset->dying_tasks)); | |
| 4402 | − | |
| 4403 | − if (!list_empty(&cset->tasks)) { | |
| 4404 | − it->task_pos = cset->tasks.next; | |
| 4405 | − it->cur_tasks_head = &cset->tasks; | |
| 4406 | − } else if (!list_empty(&cset->mg_tasks)) { | |
| 4407 | − it->task_pos = cset->mg_tasks.next; | |
| 4408 | − it->cur_tasks_head = &cset->mg_tasks; | |
| 4409 | − } else { | |
| 4410 | − it->task_pos = cset->dying_tasks.next; | |
| 4411 | − it->cur_tasks_head = &cset->dying_tasks; | |
| 4412 | 4406 | } |
| 4413 | − | |
| 4414 | − it->tasks_head = &cset->tasks; | |
| 4415 | − it->mg_tasks_head = &cset->mg_tasks; | |
| 4416 | − it->dying_tasks_head = &cset->dying_tasks; | |
| 4407 | + if (!cset) { | |
| 4408 | + it->task_pos = NULL; | |
| 4409 | + return; | |
| 4410 | + } | |
| 4411 | + it->task_pos = it->cur_tasks_head->next; | |
| 4417 | 4412 | |
| 4418 | 4413 | /* |
| 4419 | 4414 | * 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) · 38 unmodified lines | ||
| 4458 | 4453 | repeat: |
| 4459 | 4454 | if (it->task_pos) { |
| 4460 | 4455 | /* |
| 4461 | − * Advance iterator to find next entry. cset->tasks is | |
| 4462 | − * consumed first and then ->mg_tasks. After ->mg_tasks, | |
| 4463 | − * we move onto the next cset. | |
| 4456 | + * Advance iterator to find next entry. We go through cset | |
| 4457 | + * tasks, mg_tasks and dying_tasks, when consumed we move onto | |
| 4458 | + * the next cset. | |
| 4464 | 4459 | */ |
| 4465 | 4460 | if (it->flags & CSS_TASK_ITER_SKIPPED) |
| 4466 | 4461 | it->flags &= ~CSS_TASK_ITER_SKIPPED; |
| 4467 | 4462 | else |
| 4468 | 4463 | it->task_pos = it->task_pos->next; |
| 4469 | 4464 | |
| 4470 | − if (it->task_pos == it->tasks_head) { | |
| 4471 | − it->task_pos = it->mg_tasks_head->next; | |
| 4472 | − it->cur_tasks_head = it->mg_tasks_head; | |
| 4465 | + if (it->task_pos == &it->cur_cset->tasks) { | |
| 4466 | + it->cur_tasks_head = &it->cur_cset->mg_tasks; | |
| 4467 | + it->task_pos = it->cur_tasks_head->next; | |
| 4473 | 4468 | } |
| 4474 | − if (it->task_pos == it->mg_tasks_head) { | |
| 4475 | − it->task_pos = it->dying_tasks_head->next; | |
| 4476 | − it->cur_tasks_head = it->dying_tasks_head; | |
| 4469 | + if (it->task_pos == &it->cur_cset->mg_tasks) { | |
| 4470 | + it->cur_tasks_head = &it->cur_cset->dying_tasks; | |
| 4471 | + it->task_pos = it->cur_tasks_head->next; | |
| 4477 | 4472 | } |
| 4478 | − if (it->task_pos == it->dying_tasks_head) | |
| 4473 | + if (it->task_pos == &it->cur_cset->dying_tasks) | |
| 4479 | 4474 | css_task_iter_advance_css_set(it); |
| 4480 | 4475 | } else { |
| 4481 | 4476 | /* called from start, proceed to the first cset */ |
| @@ -4493,12 +4488,12 @@ repeat: · 11 unmodified lines | ||
| 4493 | 4488 | goto repeat; |
| 4494 | 4489 | |
| 4495 | 4490 | /* and dying leaders w/o live member threads */ |
| 4496 | − if (it->cur_tasks_head == it->dying_tasks_head && | |
| 4491 | + if (it->cur_tasks_head == &it->cur_cset->dying_tasks && | |
| 4497 | 4492 | !atomic_read(&task->signal->live)) |
| 4498 | 4493 | goto repeat; |
| 4499 | 4494 | } else { |
| 4500 | 4495 | /* skip all dying ones */ |
| 4501 | − if (it->cur_tasks_head == it->dying_tasks_head) | |
| 4496 | + if (it->cur_tasks_head == &it->cur_cset->dying_tasks) | |
| 4502 | 4497 | goto repeat; |
| 4503 | 4498 | } |
| 4504 | 4499 | } |