Use correct memory barrier on x86
authorAndrew Waterman <waterman@s143.Millennium.Berkeley.EDU>
Sun, 2 May 2010 20:56:54 +0000 (13:56 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:46 +0000 (17:35 -0700)
On Intel implementations of x86, SFENCE seems to only have any effect on
programs that use the write-combining buffers (e.g., those that use the
SSE instruction MOVNTPS).  Its semantics seem to NOT guarantee load-to-store
ordering.

LFENCE and SFENCE do not prevent older stores from bypassing younger
loads to different addresses, which is something a full memory barrier
should most definitely do.  So, mb() should call MFENCE, which does
have this property, not LFENCE+SFENCE.  If the latter two worked, it
may be because they happened to interlock the pipeline just enough that
the desired ordering serendipitously was enforced.

kern/arch/i686/ros/membar.h

index 1fa5df9..3d7d020 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _ARCH_MEMBAR_H
 #define _ARCH_MEMBAR_H
 
-#define mb() {rmb(); wmb();}
+#define mb() ({ asm volatile("mfence"); })
 #define rmb() ({ asm volatile("lfence"); })
 #define wmb() 
 /* Force a wmb, used in cases where an IPI could beat a write, even though