Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Jan 2001 14:24:47 -0800 (PST)
From:      John Baldwin <jhb@FreeBSD.org>
To:        hackers@FreeBSD.org
Subject:   x85 memory barriers.. ewww
Message-ID:  <XFMail.010113142447.jhb@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
Well, I wish I had a freebsd-{i386,ia32,x86} list to send this to, but I'm
having some x86 asm problems.  I'm trying to fix atomic_store_rel() and
atomic_load_acq() to actually serve as memory barriers, instead of the current
lame a = b versions we have now that don't enforce any type of barriers. 
Unfortunately, my newer versions of atomic_store_rel() that use a single 'xchg'
instruction make things _worse_.  The updated i386/include/atomic.h can be
found at: http://people.freebsd.org/~jhb/patches/atomic.h.

With the new atomic_store_rel(), I'm actually seeing caases in the mutex code
(in release_lock_quick) where for some reason the actual write out to memory is
a) being delayed, and b) not even being seen by the processor that sees it.  As
a result, a _UP_ system will spin on a spin mutex until the xchg in the
atomic_store_rel_ptr() that did the release finally propagates.  The machine
finally panics during boot when it actually succeeeds in recursing on a mutex
it had released because when it performs the atomic_cmpset() to acuiqre the
mutex, the write from the xchg has not yet been performed.  Thus it mistakenly
thinkgs it has recursed on hte mutex and never fully releases it.  Thus,
interrupts stay disabled and the next mtx_enter() of a normal mutex panic's. 
This behavior makes absolutely no since, and I have seen it on both PPro's and
PIII's.  Suggestions, comments, welcome.  The relevant part of atomic.h is this:

#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP)               \
static __inline u_##TYPE                                \
atomic_load_acq_##TYPE(volatile u_##TYPE *p)            \
{                                                       \
        u_##TYPE res;                                   \
                                                        \
        __asm __volatile(MPLOCKED LOP                   \
        : "=a" (res)                    /* 0 (result) */\
        : "m" (*p)                      /* 1 */         \
        : "memory");                                    \
                                                        \
        return (res);                                   \
}                                                       \
                                                        \
/*                                                      \
 * The XCHG instruction asserts LOCK automagically.     \
 */                                                     \
static __inline void                                    \
atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
{                                                       \
        __asm __volatile(SOP                            \
        : "=m" (*p)                     /* 0 */         \
        : "r" (v)                       /* 1 */         \
        : "memory");                                    \
}
#endif  /* defined(I386_CPU) */
#endif  /* defined(KLD_MODULE) */

ATOMIC_STORE_LOAD(char, "cmpxchgb %b0,%1", "xchgb %b1,%0")
ATOMIC_STORE_LOAD(short,"cmpxchgw %w0,%1", "xchgw %w1,%0")
ATOMIC_STORE_LOAD(int,  "cmpxchgl %0,%1",  "xchgl %1,%0")
ATOMIC_STORE_LOAD(long, "cmpxchgl %0,%1",  "xchgl %1,%0")

Actually, I am probably just screwing up the clobbers, thinking about this. 
Thanks to whoever points out the obvious brain-o.

-- 

John Baldwin <jhb@FreeBSD.org> -- http://www.FreeBSD.org/~jhb/
PGP Key: http://www.baldwin.cx/~john/pgpkey.asc
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.010113142447.jhb>