[parisc-linux] missing barrier in _raw_spin_lock?
arndb at onlinehome.de
arndb at onlinehome.de
Sun Jan 25 10:10:01 MST 2004
John David Anglin <dave at hiauly1.hia.nrc.ca> schrieb am 25.01.2004,
07:13:10:
> > Anyway, gcc doesn't seem to be that smart:
>
> Right, it not that smart but it does optimize certain memory references.
>
> > The key bit is __ldcw() in asm/system.h:
> >
> > /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */
> > #define __ldcw(a) ({ \
> > unsigned __ret; \
> > __asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \
> > __ret; \
> > })
>
> In some version of pthreads, we used
>
> #define __ldcw(a) ({ \
> unsigned int __ret; \
> __asm__ __volatile__("ldcw 0(%2),%0" \
> : "=r" (__ret), "=m" (*(a)) : "r" (a)); \
> __ret; \
> })
>
> This tells gcc explicitly what memory is affected by the asm. However,
> it doesn't provide a memory barrier. I think this isn't necessary in
> pthreads because it provides a separate macro define for this.
I suppose the memory operand specification is required here. Newer
compilers (especially gcc-3.4) can optimize away local variables if you
only access the address but not the contents. I think even your
pthreads version is not really correct, because it specifies (*(a)) as
output only instead of inout.
> #include
>
> static spinlock_t lock = SPIN_LOCK_UNLOCKED;
>
> void test(int *x)
> {
> if (*x)
> {
> spin_lock(&lock);
> if (!*x)
> *x = 0x1234;
> spin_unlock(&lock);
> }
> }
>
> We need the "memory" clobber in SMP. I think the macro should be:
>
> #define __ldcw(a) ({ \
> unsigned int __ret; \
> __asm__ __volatile__("ldcw 0(%2),%0" \
> : "=r" (__ret), "=m" (*(a)) : "r" (a) : "memory"); \
> __ret; \
> })
No, putting the barrier into __ldcw is wrong because it would impact all
other uses of __ldcw that don't need the barrier. AFAICS, the
_raw_spin_lock needs to be changed to the below.
#define _raw_spin_lock(x) do { \
while (__ldcw (&(x)->lock) == 0) \
while (((x)->lock) == 0) ; \
barrier(); } while (0)
Since the assembly output of the test program with gcc-3.3 looks good,
this probably did not do any harm so far.
Arnd <><
More information about the parisc-linux
mailing list