--- 2.4.0-test11-pre2/kernel/sched.c.~1~ Fri Nov 10 12:21:49 2000 +++ 2.4.0-test11-pre2/kernel/sched.c Sat Nov 11 23:40:35 2000 @@ -433,15 +433,27 @@ int policy; /* + * prev->policy can be written from here only before `prev' + * can be scheduled (before setting prev->has_cpu to zero). + * Of course it must also be read before allowing prev + * to be rescheduled, but since the write depends on the read + * to complete, wmb() is enough. (the spin_lock() acquired + * before setting has_cpu is not enough because the spin_lock() + * common code semantics allows code outside the critical section + * to enter inside the critical section) + */ + policy = prev->policy; + prev->policy = policy & ~SCHED_YIELD; + wmb(); + + /* * fast path falls through. We have to clear has_cpu before * checking prev->state to avoid a wakeup race - thus we * also have to protect against the task exiting early. */ task_lock(prev); - policy = prev->policy; - prev->policy = policy & ~SCHED_YIELD; prev->has_cpu = 0; - wmb(); + mb(); if (prev->state == TASK_RUNNING) goto needs_resched;