Commit de69a80b authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

sched: Stop buddies from hogging the system

Clear buddies more agressively.

The (theoretical, haven't actually observed any of this) problem is
that when we do not select either buddy in pick_next_entity()
because they are too far ahead of the left-most task, we do not
clear the buddies.

This means that as soon as we service the left-most task, these
same buddies will be tried again on the next schedule. Now if the
left-most task was a pure hog, it wouldn't have done any wakeups
and it wouldn't have set buddies of its own. That leads to the old
buddies dominating, which would lead to bad latencies.
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
LKML-Reference: <new-submission>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent ad4b78bb
...@@ -764,10 +764,10 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) ...@@ -764,10 +764,10 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
static void __clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se) static void __clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
{ {
if (cfs_rq->last == se) if (!se || cfs_rq->last == se)
cfs_rq->last = NULL; cfs_rq->last = NULL;
if (cfs_rq->next == se) if (!se || cfs_rq->next == se)
cfs_rq->next = NULL; cfs_rq->next = NULL;
} }
...@@ -1646,8 +1646,13 @@ static struct task_struct *pick_next_task_fair(struct rq *rq) ...@@ -1646,8 +1646,13 @@ static struct task_struct *pick_next_task_fair(struct rq *rq)
/* /*
* If se was a buddy, clear it so that it will have to earn * If se was a buddy, clear it so that it will have to earn
* the favour again. * the favour again.
*
* If se was not a buddy, clear the buddies because neither
* was elegible to run, let them earn it again.
*
* IOW. unconditionally clear buddies.
*/ */
__clear_buddies(cfs_rq, se); __clear_buddies(cfs_rq, NULL);
set_next_entity(cfs_rq, se); set_next_entity(cfs_rq, se);
cfs_rq = group_cfs_rq(se); cfs_rq = group_cfs_rq(se);
} while (cfs_rq); } while (cfs_rq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment