From: Nick Piggin <nickpiggin@yahoo.com.au>

Hmm, patch 3/4 added the following comment:
/* FIXME: updates to ->parent are racy */

After getting some sleep, it appears to be easily fixed instead of leaving the
FIXME for someone else ;)

This is probably faster too because you're not doing the additional
local_irq_save/restore pair.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/kernel/sched.c |   13 +++++--------
 1 files changed, 5 insertions(+), 8 deletions(-)

diff -puN kernel/sched.c~sched-exit-race kernel/sched.c
--- 25/kernel/sched.c~sched-exit-race	2004-06-25 02:50:09.643107192 -0700
+++ 25-akpm/kernel/sched.c	2004-06-25 02:50:09.649106280 -0700
@@ -1051,19 +1051,16 @@ void fastcall sched_exit(task_t * p)
 	unsigned long flags;
 	runqueue_t *rq;
 
-	local_irq_save(flags);
-	if (p->first_time_slice) {
-		/* FIXME: updates to ->parent are racy */
-		p->parent->time_slice += p->time_slice;
-		if (unlikely(p->parent->time_slice > MAX_TIMESLICE))
-			p->parent->time_slice = MAX_TIMESLICE;
-	}
-	local_irq_restore(flags);
 	/*
 	 * 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) {
+		p->parent->time_slice += p->time_slice;
+		if (unlikely(p->parent->time_slice > MAX_TIMESLICE))
+			p->parent->time_slice = MAX_TIMESLICE;
+	}
 	if (p->sleep_avg < p->parent->sleep_avg)
 		p->parent->sleep_avg = p->parent->sleep_avg /
 		(EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg /
_