sched/rt: Fix bad task migration for rt tasks
[platform/kernel/linux-starfive.git] / kernel / sched / rt.c
index ed2a47e..4f5796d 100644 (file)
@@ -1777,6 +1777,8 @@ static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq)
        BUG_ON(idx >= MAX_RT_PRIO);
 
        queue = array->queue + idx;
+       if (SCHED_WARN_ON(list_empty(queue)))
+               return NULL;
        next = list_entry(queue->next, struct sched_rt_entity, run_list);
 
        return next;
@@ -1789,7 +1791,8 @@ static struct task_struct *_pick_next_task_rt(struct rq *rq)
 
        do {
                rt_se = pick_next_rt_entity(rt_rq);
-               BUG_ON(!rt_se);
+               if (unlikely(!rt_se))
+                       return NULL;
                rt_rq = group_rt_rq(rt_se);
        } while (rt_rq);
 
@@ -1997,11 +2000,15 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq)
                         * the mean time, task could have
                         * migrated already or had its affinity changed.
                         * Also make sure that it wasn't scheduled on its rq.
+                        * It is possible the task was scheduled, set
+                        * "migrate_disabled" and then got preempted, so we must
+                        * check the task migration disable flag here too.
                         */
                        if (unlikely(task_rq(task) != rq ||
                                     !cpumask_test_cpu(lowest_rq->cpu, &task->cpus_mask) ||
                                     task_on_cpu(rq, task) ||
                                     !rt_task(task) ||
+                                    is_migration_disabled(task) ||
                                     !task_on_rq_queued(task))) {
 
                                double_unlock_balance(rq, lowest_rq);