[PATCH] kernel/sched/rt: Add a rescheduling point

From: Sebastian Andrzej Siewior
Date: Tue Jan 24 2017 - 09:40:22 EST


Since the change in commit fd7a4bed1835 ("sched, rt: Convert
switched_{from, to}_rt() / prio_changed_rt() to balance callbacks") we
don't reschedule a task under certain circumstances:

Lets say taskA, SCHED_OTHER, is running on CPU0 (and it may run only on
CPU0) and holds a PI lock. This task is removed from the CPU because it
used up its time slice and another SCHED_OTHER task is running. TaskB on
CPU1 runs at RT priority and asks for the lock owned by taskA. This
results in a priority boost for taskA. TaskB goes to sleep until the
lock has been made available. TaskA is already runable (but not active)
so it receives no wake up.
The reality now is that taskA gets on the CPU once the scheduler decides
to remove the current task despite the fact that a high priority task is
enqueued and waiting. This may take a long time.
The desired behaviour is that CPU0 immediately reschedules after the
priority boost which made taskA the task with the lowest priority.

Fixes: fd7a4bed1835 ("sched, rt: Convert switched_{from, to}_rt() /
prio_changed_rt() to balance callbacks")
Suggested-by: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
---
kernel/sched/rt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 88254be118b0..cdba8d58dbc5 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -2198,10 +2198,10 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p)
#ifdef CONFIG_SMP
if (tsk_nr_cpus_allowed(p) > 1 && rq->rt.overloaded)
queue_push_tasks(rq);
-#else
+ else
+#endif /* CONFIG_SMP */
if (p->prio < rq->curr->prio)
resched_curr(rq);
-#endif /* CONFIG_SMP */
}
}

--
2.11.0