linux-mips
[Top] [All Lists]

Re: Atomicity & preemptive kernels

To: Justin Carlson <justin@cs.cmu.edu>
Subject: Re: Atomicity & preemptive kernels
From: Jun Sun <jsun@mvista.com>
Date: Tue, 11 Jun 2002 11:44:04 -0700
Cc: linux-mips@oss.sgi.com
References: <1023738247.1133.56.camel@localhost.localdomain> <3D0524B5.403@mvista.com> <1023753603.1152.28.camel@localhost.localdomain>
Sender: owner-linux-mips@oss.sgi.com
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.2.1) Gecko/20010901
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



<Prev in Thread] Current Thread [Next in Thread>