ANDROID: sched/pause: migrate_tasks crash

With DEQUEUE_SAVE and ENQUEUE_RESTORE set when calling deactivate_task
and activate_task, the rt class scheduler will not dequeue/enqueue
the task respectively - move_entity() returns false. This results in
the same task being picked multiple times by __pick_migrate_task,
which results in the same task getting a second initialization of
next->percpu_kthread_node, corrupting the list and causing a crash
with __list_add_valid.

Remove DEQUEUE_SAVE and ENQUEUE_RESTORE when holding back kthreads from
being migrated, for the calls to activate/deactivate task,
preventing the crash.

Bug: 180893027
Change-Id: I3171c26a4f9415287feb5acfe933b4442ca05937
Signed-off-by: Stephen Dickey <dickey@codeaurora.org>
This commit is contained in:
Stephen Dickey 2021-02-22 09:34:21 -08:00
parent 7dddba0c69
commit 9d1a51d1b9
1 changed files with 6 additions and 2 deletions

View File

@ -6940,8 +6940,10 @@ static void migrate_tasks(struct rq *dead_rq, struct rq_flags *rf, bool force)
if (!force && is_per_cpu_kthread(next)) {
INIT_LIST_HEAD(&next->percpu_kthread_node);
list_add(&next->percpu_kthread_node, &percpu_kthreads);
/* DEQUEUE_SAVE not used due to move_entity in rt */
deactivate_task(rq, next,
DEQUEUE_NOCLOCK | DEQUEUE_SAVE);
DEQUEUE_NOCLOCK);
continue;
}
@ -6989,7 +6991,9 @@ static void migrate_tasks(struct rq *dead_rq, struct rq_flags *rf, bool force)
list_for_each_entry_safe(next, tmp, &percpu_kthreads,
percpu_kthread_node) {
activate_task(rq, next, ENQUEUE_NOCLOCK | ENQUEUE_RESTORE);
/* ENQUEUE_RESTORE not used due to move_entity in rt */
activate_task(rq, next, ENQUEUE_NOCLOCK);
list_del(&next->percpu_kthread_node);
}