diff options
author | Peter Zijlstra <peterz@infradead.org> | 2017-03-01 10:51:47 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-03-02 08:50:17 +0100 |
commit | 0ba87bb27d66b78e278167ac7e20c66520b8a612 (patch) | |
tree | 60797a972454cf334869606e5097ef9d9b5d3599 /kernel | |
parent | 4c77b18cf8b7ab37c7d5737b4609010d2ceec5f0 (diff) | |
download | op-kernel-dev-0ba87bb27d66b78e278167ac7e20c66520b8a612.zip op-kernel-dev-0ba87bb27d66b78e278167ac7e20c66520b8a612.tar.gz |
sched/core: Fix pick_next_task() for RT,DL
Pavan noticed that the following commit:
49ee576809d8 ("sched/core: Optimize pick_next_task() for idle_sched_class")
... broke RT,DL balancing by robbing them of the opportinty to do new-'idle'
balancing when their last runnable task (on that runqueue) goes away.
Reported-by: Pavan Kondeti <pkondeti@codeaurora.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Fixes: 49ee576809d8 ("sched/core: Optimize pick_next_task() for idle_sched_class")
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched/core.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index bbfb917..6699d43a 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3273,10 +3273,15 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) struct task_struct *p; /* - * Optimization: we know that if all tasks are in - * the fair class we can call that function directly: + * Optimization: we know that if all tasks are in the fair class we can + * call that function directly, but only if the @prev task wasn't of a + * higher scheduling class, because otherwise those loose the + * opportunity to pull in more work from other CPUs. */ - if (likely(rq->nr_running == rq->cfs.h_nr_running)) { + if (likely((prev->sched_class == &idle_sched_class || + prev->sched_class == &fair_sched_class) && + rq->nr_running == rq->cfs.h_nr_running)) { + p = fair_sched_class.pick_next_task(rq, prev, rf); if (unlikely(p == RETRY_TASK)) goto again; |