Re: [patch] Re: spin_unlock optimization(i386)

Jamie Lokier (lkd@tantalophile.demon.co.uk)
Mon, 22 Nov 1999 10:38:15 +0100


Gerard Roudier wrote:
> > OTOH, I don't see how speculative reads can be a problem. You're
> > speculatively reading from /outside/ a locked region so anything goes.
>
> I wrote "/around/ the 'mov'" and it seemed obvious to me that this
> also included code that is executed /inside/ the locked region.

Ah, good point. Reads in the program before the unlock might be
performed after the unlock in the processor.

> > If local speculative reads are a problem, perhaps this would be faster
> > than "lock; btrl $0,%0":
> >
> > "movl $0,%0" then rmb().
>
> I thought about speculations that involve other variables that may be
> performed before the 'mov', or in parallel with the 'mov' and results used
> after the 'mov'. This makes your rmb() just miss the train.

You are right. Here's the solutions (perhaps).

An rmb() will prevent reads that occur before it from being
speculatively executed after it, and vice versa. rmb() expands to asm
volatile ("lock; addl $0,0(%esp)" : : : "memory"). Being a locked
operation it serves as a processor barrier for both reads and writes;
being in cache, it is fast on a PPro. The "memory" constraint makes it
a compiler memory barrier; register operations can still be reordered
around it in theory. That's ok.

To ensure critical-section reads execute before the unlock, the rmb()
must come /before/ the unlock operation. Reads in the program after the
unlock are non-critical. Therefore this should work:

rmb() then "movl $0,%0".

Enjoy,
-- Jamie

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/