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.
Unified · Split
| @@ -7444,8 +7444,12 @@ void sched_move_task(struct task_struct *tsk) · 7443 unmodified lines | ||
| 7444 | 7444 | if (unlikely(running)) |
| 7445 | 7445 | put_prev_task(rq, tsk); |
| 7446 | 7446 | |
| 7447 | − tg = container_of(task_css_check(tsk, cpu_cgrp_id, | |
| 7448 | − lockdep_is_held(&tsk->sighand->siglock)), | |
| 7447 | + /* | |
| 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 | 7453 | struct task_group, css); |
| 7450 | 7454 | tg = autogroup_task_group(tsk, tg); |
| 7451 | 7455 | tsk->sched_task_group = tg; |