From ccabb0e3654dcef3a35a2d0693a85881a945e001 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 9 Feb 2022 18:11:25 +0000 Subject: [PATCH] ANDROID: sched: Don't allow frozen asymmetric tasks to remain on the rq If a task with a restricted possible CPU mask and PF_FROZEN or PF_FREEZER_SKIP set blocks, then we must not put it back on the runqueue to handle a signal because this could lead to migration failures later on if the suspending CPU is not capable of running it. Return such a task to the runqueue only if a fatal signal is pending, and otherwise allow the task to block. Bug: 202918514 Signed-off-by: Will Deacon Change-Id: I04cc9e65751f2bffc556c4da9ef02fe386764324 --- kernel/sched/core.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 227c054eee24..7a0fd9d23838 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6223,6 +6223,23 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) #endif /* CONFIG_SCHED_CORE */ +static bool __task_can_run(struct task_struct *prev) +{ + if (__fatal_signal_pending(prev)) + return true; + + if (!frozen_or_skipped(prev)) + return true; + + /* + * We can't safely go back on the runqueue if we're an asymmetric + * task skipping the freezer. Doing so can lead to migration failures + * later on if there aren't any suitable CPUs left around for us to + * move to. + */ + return task_cpu_possible_mask(prev) == cpu_possible_mask; +} + /* * Constants for the sched_mode argument of __schedule(). * @@ -6334,7 +6351,7 @@ static void __sched notrace __schedule(unsigned int sched_mode) */ prev_state = READ_ONCE(prev->__state); if (!(sched_mode & SM_MASK_PREEMPT) && prev_state) { - if (signal_pending_state(prev_state, prev)) { + if (signal_pending_state(prev_state, prev) && __task_can_run(prev)) { WRITE_ONCE(prev->__state, TASK_RUNNING); } else { prev->sched_contributes_to_load =