Justin Carlson wrote: > On Mon, 2002-06-10 at 15:14, Jun Sun wrote: > >>I am not sure if I am following your logic, but I don't see a race condition here. >> >>Once current->mm is read into a register, the register is saved into stack >>when an interrupt happens (which later incurs a reschedule presumbably). When >>the current preempted process comes back later, it goes back to the "tail" of >>do_IRQ(), followed by restoring the registers. Since the register now holds >>the right value, set_entryhi() should be correct. >> >> > > You've described exactly what happens. The only problem is, it's > possible the underlying value for current->mm has changed. It's a > *really* narrow window, at most a cycle or two, but I think it is > there. In addition, even if you hit the window, to trigger wrong > behavior it requires that you also saturate the local ASID space, > invoking the tlb flush and asid reset in get_mmu_context(). > > The change that's introduced by the preemptive kernel is that > switch_mm() can be called after an interrupt. So, with some > hypothetical assembly, the code flow looks like this: > > lw $1, 120($29) ; Load current->mm->context into a register > * Interrupt happens * > * reschedule happens, switch_mm() is called * > * get_new_mmu_context() invoked, starts a new ASID cycle. > * current->mm->context for the original process changes > * (sometime later) switch back to original process > mtc0 $entryhi, $1 ; stale context put back into entryhi! > > Does that make more sense? It's really a tiny race, but I think it's a > real one. > I see your point now. However, the race is not there. switch_mm() is only called from inside schedule() function, which as a whole is preemption-safe. In other words, the above event sequence won't cause a context switch until we exit from schedule() function. Jun