sched_move_task() is the only interface to change sched_task_group: cpu_cgrp_subsys methods and autogroup_move_group() use it. Everything is synchronized by task_rq_lock(), so cpu_cgroup_attach() is ordered with other users of sched_move_task(). This means we do no need RCU here: if we've dereferenced a tg here, the .attach method hasn't been called for it yet. Thus, we should pass "true" to task_css_check() to silence lockdep warnings.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -7444,8 +7444,12 @@ void sched_move_task(struct task_struct *tsk) · 7443 unmodified lines | |||
| 7444 | if (unlikely(running)) | 7444 | if (unlikely(running)) |
| 7445 | put_prev_task(rq, tsk); | 7445 | put_prev_task(rq, tsk); |
| 7446 | 7446 | ||
| 7447 | tg = container_of(task_css_check(tsk, cpu_cgrp_id, | 7447 | /* |
| 7448 | lockdep_is_held(&tsk->sighand->siglock)), | 7448 | * All callers are synchronized by task_rq_lock(); we do not use RCU |
| 7449 | * which is pointless here. Thus, we pass "true" to task_css_check() | ||
| 7450 | * to prevent lockdep warnings. | ||
| 7451 | */ | ||
| 7452 | tg = container_of(task_css_check(tsk, cpu_cgrp_id, true), | ||
| 7449 | struct task_group, css); | 7453 | struct task_group, css); |
| 7450 | tg = autogroup_task_group(tsk, tg); | 7454 | tg = autogroup_task_group(tsk, tg); |
| 7451 | tsk->sched_task_group = tg; | 7455 | tsk->sched_task_group = tg; |