summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2004-08-23 21:11:02 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-23 21:11:02 -0700
commitd513047ba6cc4638debe778ee6fc40acf46cc583 (patch)
tree7021e94cf8753324ad7b82ea4173b3c66aaa78fc /kernel
parent68b4cdb8cb1c6243b3ebca686ca5086b34142c4d (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.c24
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);
}
/*