[openib-general] Re: Re: ipoib_mcast_send.patch
Michael S. Tsirkin
mst at mellanox.co.il
Wed Feb 8 12:22:38 PST 2006
Quoting r. Roland Dreier <rdreier at cisco.com>:
> Subject: Re: Re: ipoib_mcast_send.patch
>
> Michael> Right, but I thought atomic test_and_set_bit implied
> Michael> smp_wmb already?
>
> So did I but then I looked in the kernel source and now I think that
> set_bit operations are only ordered against other bitops that touch
> the same word. For example ia64 just uses cmpxchg to implement the
> bitops, and powerpc just uses locked loads and stores.
>
> - R.
>
Hmm. Roland, which kernel version is that?
On 2.6.15 I see in include/asm-powerpc/bitops.h
static __inline__ int test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
{
unsigned long old, t;
unsigned long mask = BITOP_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
__asm__ __volatile__(
EIEIO_ON_SMP
"1:" PPC_LLARX "%0,0,%3 # test_and_set_bit\n"
"or %1,%0,%2 \n"
PPC405_ERR77(0,%3)
PPC_STLCX "%1,0,%3 \n"
"bne- 1b"
ISYNC_ON_SMP
: "=&r" (old), "=&r" (t)
: "r" (mask), "r" (p)
: "cc", "memory");
return (old & mask) != 0;
}
EIEIO_ON_SMP is a write barrier on smp, isnt it?
I see this in 2.6.11: include/asm-ppc64/bitops.h
static __inline__ int test_and_set_bit(unsigned long nr, volatile unsigned long
*addr)
{
unsigned long old, t;
unsigned long mask = 1UL << (nr & 0x3f);
unsigned long *p = ((unsigned long *)addr) + (nr >> 6);
__asm__ __volatile__(
EIEIO_ON_SMP
"1: ldarx %0,0,%3 # test_and_set_bit\n\
or %1,%0,%2 \n\
stdcx. %1,0,%3 \n\
bne- 1b"
ISYNC_ON_SMP
: "=&r" (old), "=&r" (t)
: "r" (mask), "r" (p)
: "cc", "memory");
return (old & mask) != 0;
}
EIEIO_ON_SMP is exactly what is needed, no?
/*
* The test_and_*_bit operations are taken to imply a memory barrier
* on SMP systems.
*/
...
/*
* test_and_*_bit do imply a memory barrier (?)
*/
static __inline__ int test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned int old, t;
unsigned int mask = 1 << (nr & 0x1f);
volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
__asm__ __volatile__(SMP_WMB "\n\
1: lwarx %0,0,%4 \n\
or %1,%0,%3 \n"
PPC405_ERR77(0,%4)
" stwcx. %1,0,%4 \n\
bne 1b"
SMP_MB
: "=&r" (old), "=&r" (t), "=m" (*p)
: "r" (mask), "r" (p), "m" (*p)
: "cc", "memory");
return (old & mask) != 0;
}
Ahem. It does look to me like atomics imply smp_wmb.
--
Michael S. Tsirkin
Staff Engineer, Mellanox Technologies
More information about the general
mailing list