Commit d513047b authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[PATCH] sched: new task fix

Rusty noticed that we update the parent ->avg_sleep without holding the
runqueue lock. Also the code needed cleanups.
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 68b4cdb8
...@@ -1341,7 +1341,7 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags) ...@@ -1341,7 +1341,7 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags)
{ {
unsigned long flags; unsigned long flags;
int this_cpu, cpu; int this_cpu, cpu;
runqueue_t *rq; runqueue_t *rq, *this_rq;
rq = task_rq_lock(p, &flags); rq = task_rq_lock(p, &flags);
cpu = task_cpu(p); cpu = task_cpu(p);
...@@ -1383,8 +1383,15 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags) ...@@ -1383,8 +1383,15 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags)
} else } else
/* Run child last */ /* Run child last */
__activate_task(p, rq); __activate_task(p, rq);
/*
* We skip the following code due to cpu == this_cpu
*
* task_rq_unlock(rq, &flags);
* this_rq = task_rq_lock(current, &flags);
*/
this_rq = rq;
} else { } else {
runqueue_t *this_rq = cpu_rq(this_cpu); this_rq = cpu_rq(this_cpu);
/* /*
* Not the local CPU - must adjust timestamp. This should * Not the local CPU - must adjust timestamp. This should
...@@ -1396,18 +1403,17 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags) ...@@ -1396,18 +1403,17 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags)
if (TASK_PREEMPTS_CURR(p, rq)) if (TASK_PREEMPTS_CURR(p, rq))
resched_task(rq->curr); resched_task(rq->curr);
current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) *
PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
schedstat_inc(rq, wunt_moved); schedstat_inc(rq, wunt_moved);
} /*
* Parent and child are on different CPUs, now get the
if (unlikely(cpu != this_cpu)) { * parent runqueue to update the parent's ->sleep_avg:
*/
task_rq_unlock(rq, &flags); task_rq_unlock(rq, &flags);
rq = task_rq_lock(current, &flags); this_rq = task_rq_lock(current, &flags);
} }
current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) * current->sleep_avg = JIFFIES_TO_NS(CURRENT_BONUS(current) *
PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS); PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS);
task_rq_unlock(rq, &flags); task_rq_unlock(this_rq, &flags);
} }
/* /*
......
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