diff options
| author | Ingo Molnar <mingo@elte.hu> | 2004-08-23 21:11:02 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-23 21:11:02 -0700 |
| commit | d513047ba6cc4638debe778ee6fc40acf46cc583 (patch) | |
| tree | 7021e94cf8753324ad7b82ea4173b3c66aaa78fc /kernel | |
| parent | 68b4cdb8cb1c6243b3ebca686ca5086b34142c4d (diff) | |
[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: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index c4ba3805a4fb..5f21f757be1d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1341,7 +1341,7 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags) { unsigned long flags; int this_cpu, cpu; - runqueue_t *rq; + runqueue_t *rq, *this_rq; rq = task_rq_lock(p, &flags); cpu = task_cpu(p); @@ -1383,8 +1383,15 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags) } else /* Run child last */ __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 { - runqueue_t *this_rq = cpu_rq(this_cpu); + this_rq = cpu_rq(this_cpu); /* * 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) if (TASK_PREEMPTS_CURR(p, rq)) 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); - } - - if (unlikely(cpu != this_cpu)) { + /* + * Parent and child are on different CPUs, now get the + * parent runqueue to update the parent's ->sleep_avg: + */ 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) * PARENT_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS); - task_rq_unlock(rq, &flags); + task_rq_unlock(this_rq, &flags); } /* |
