summaryrefslogtreecommitdiff
path: root/kernel/sched/core.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-04-06 19:35:03 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-04-06 19:35:03 -0400
commitfccfb9950836524d79260448fba6131f6b1d73c3 (patch)
treea6fef32e330852138d9e7bd12d7b3dd97c4360c3 /kernel/sched/core.c
parentd597580d373774b1bdab84b3d26ff0b55162b916 (diff)
parentb4fb8f66f1ae2e167d06c12d018025a8d4d3ba7e (diff)
Merge commit 'b4fb8f66f1ae2e167d06c12d018025a8d4d3ba7e' into uaccess.ia64
backmerge of mainline ia64 fix
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r--kernel/sched/core.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 956383844116..3b31fc05a0f1 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3287,10 +3287,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;