diff -urN ref/include/linux/sched.h 2.4.4aa3/include/linux/sched.h --- ref/include/linux/sched.h Tue May 1 19:24:09 2001 +++ 2.4.4aa3/include/linux/sched.h Tue May 1 17:20:05 2001 @@ -301,7 +301,7 @@ * all fields in a single cacheline that are needed for * the goodness() loop in schedule(). */ - int counter; + volatile int counter; int nice; unsigned int policy; struct mm_struct *mm; diff -urN ref/kernel/fork.c 2.4.4aa3/kernel/fork.c --- ref/kernel/fork.c Tue May 1 19:24:09 2001 +++ 2.4.4aa3/kernel/fork.c Tue May 1 19:26:10 2001 @@ -666,17 +666,18 @@ p->pdeath_signal = 0; /* - * Give the parent's dynamic priority entirely to the child. The - * total amount of dynamic priorities in the system doesn't change - * (more scheduling fairness), but the child will run first, which - * is especially useful in avoiding a lot of copy-on-write faults - * if the child for a fork() just wants to do a few simple things - * and then exec(). This is only important in the first timeslice. - * In the long run, the scheduling behavior is unchanged. + * Scheduling the child first is especially useful in avoiding a + * lot of copy-on-write faults if the child for a fork() just wants + * to do a few simple things and then exec(). */ - p->counter = current->counter; - current->counter = 0; - current->need_resched = 1; + { + int counter = current->counter; + p->counter = (counter + 1) >> 1; + current->counter = counter >> 1; + p->policy &= ~SCHED_YIELD; + current->policy |= SCHED_YIELD; + current->need_resched = 1; + } /* Tell the parent if it can get back its timeslice when child exits */ p->get_child_timeslice = 1;