sched, cgroup: Fixup broken cgroup movement
PATCH 23/28 sched, cgroup: Fixup broken cgroup movement
Commit: b2b5ce022acf5e9f52f7b78c5579994fdde191d4 upstream
Author: Peter Zijlstra <[email protected]>
AuthorDate: Fri Oct 15 15:24:15 2010 +0200
Dima noticed that we fail to correct the ->vruntime of sleeping tasks when we move them between cgroups.
Reported-by Dima Zavin <[email protected]>
Signed-off-by Peter Zijlstra <[email protected]>
Tested-by Mike Galbraith <[email protected]>
LKML-Reference: <1287150604.29097.1513.camel@twins>
Signed-off-by Ingo Molnar <[email protected]>
Signed-off-by Mike Galbraith <[email protected]>
Acked-by Peter Zijlstra <[email protected]>
--- include/linux/sched.h | 2 +- kernel/sched.c | 8 ++++---- kernel/sched_fair.c | 25 +++++++++++++++++++------ 3 files changed, 24 insertions(+), 11 deletions(-)
include/linux/sched.h +1 -1
@@ -1113,7 +1113,7 @@ struct sched_class { struct task_struct *task);#ifdef CONFIG_FAIR_GROUP_SCHED -void (*moved_group) (struct task_struct *p,int on_rq); +void (*task_move_group) (struct task_struct *p,int on_rq);#endif };
kernel/sched.c +4 -4
@@ -10224,12 +10224,12 @@ void sched_move_task(struct task_struct *tsk)if (unlikely (running)) tsk->sched_class->put_prev_task (rq, tsk); -set_task_rq (tsk,task_cpu (tsk)); -#ifdef CONFIG_FAIR_GROUP_SCHED -if (tsk->sched_class->moved_group) - tsk->sched_class->moved_group (tsk, on_rq); +if (tsk->sched_class->task_move_group) + tsk->sched_class->task_move_group (tsk, on_rq); + else#endif +set_task_rq (tsk,task_cpu (tsk));if (unlikely (running)) tsk->sched_class->set_curr_task (rq);
kernel/sched_fair.c +19 -6
@@ -2068,13 +2068,26 @@ static void set_curr_task_fair(struct rq *rq) }#ifdef CONFIG_FAIR_GROUP_SCHED -static void moved_group_fair (struct task_struct *p,int on_rq) +static void task_move_group_fair (struct task_struct *p,int on_rq) { -struct cfs_rq *cfs_rq =task_cfs_rq (p); - -update_curr (cfs_rq); +/* +* If the task was not on the rq at the time of this cgroup movement +* it must have been asleep, sleeping tasks keep their ->vruntime +* absolute on their old rq until wakeup (needed for the fair sleeper +* bonus in place_entity()). +* +* If it was on the rq, we've just 'preempted' it, which does convert +* ->vruntime to a relative base. +* +* Make sure both cases convert their relative position when migrating +* to another cgroup's rq. This does somewhat interfere with the +* fair sleeper stuff for the first placement, but who cares. +*/ +if (!on_rq) + p->se.vruntime -=cfs_rq_of (&p->se)->min_vruntime; +set_task_rq (p,task_cpu (p));if (!on_rq) -place_entity (cfs_rq, &p->se,1 ); + p->se.vruntime +=cfs_rq_of (&p->se)->min_vruntime; }#endif
@@ -2128,7 +2141,7 @@ static const struct sched_class fair_sched_class = { .get_rr_interval = get_rr_interval_fair, #ifdef CONFIG_FAIR_GROUP_SCHED - .moved_group = moved_group_fair, + .task_move_group = task_move_group_fair,#endif };
Signature · 1 line
1.7.4