From: Oleg Nesterov sched_exit: if (parent->time_slice > task_timeslice(p))) parent->time_slice = task_timeslice(p) I think it should use task_timeslice(parent) instead. The patch looks complicated, but it is not. It just caches the value of 'p->parent'. Signed-off-by: Oleg Nesterov Cc: Ingo Molnar Cc: Nick Piggin Cc: Con Kolivas Cc: Peter Williams Signed-off-by: Andrew Morton --- kernel/sched.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff -puN kernel/sched.c~sched_exit-fix-parent-time_slice-calculation kernel/sched.c --- a/kernel/sched.c~sched_exit-fix-parent-time_slice-calculation +++ a/kernel/sched.c @@ -1606,6 +1606,7 @@ void fastcall wake_up_new_task(task_t *p */ void fastcall sched_exit(task_t *p) { + task_t *parent = p->parent; unsigned long flags; runqueue_t *rq; @@ -1613,14 +1614,14 @@ void fastcall sched_exit(task_t *p) * If the child was a (relative-) CPU hog then decrease * the sleep_avg of the parent as well. */ - rq = task_rq_lock(p->parent, &flags); - if (p->first_time_slice && task_cpu(p) == task_cpu(p->parent)) { - p->parent->time_slice += p->time_slice; - if (unlikely(p->parent->time_slice > task_timeslice(p))) - p->parent->time_slice = task_timeslice(p); + rq = task_rq_lock(parent, &flags); + if (p->first_time_slice && task_cpu(p) == task_cpu(parent)) { + parent->time_slice += p->time_slice; + if (unlikely(parent->time_slice > task_timeslice(parent))) + parent->time_slice = task_timeslice(parent); } - if (p->sleep_avg < p->parent->sleep_avg) - p->parent->sleep_avg = p->parent->sleep_avg / + if (p->sleep_avg < parent->sleep_avg) + parent->sleep_avg = parent->sleep_avg / (EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg / (EXIT_WEIGHT + 1); task_rq_unlock(rq, &flags); _