]> Pileus Git - ~andy/linux/commitdiff
x86: optimise barriers
authorNick Piggin <npiggin@suse.de>
Sat, 13 Oct 2007 01:07:38 +0000 (03:07 +0200)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 13 Oct 2007 01:41:21 +0000 (18:41 -0700)
According to latest memory ordering specification documents from Intel
and AMD, both manufacturers are committed to in-order loads from
cacheable memory for the x86 architecture.  Hence, smp_rmb() may be a
simple barrier.

Also according to those documents, and according to existing practice in
Linux (eg.  spin_unlock doesn't enforce ordering), stores to cacheable
memory are visible in program order too.  Special string stores are safe
-- their constituent stores may be out of order, but they must complete
in order WRT surrounding stores.  Nontemporal stores to WB memory can go
out of order, and so they should be fenced explicitly to make them
appear in-order WRT other stores.  Hence, smp_wmb() may be a simple
barrier.

    http://developer.intel.com/products/processor/manuals/318147.pdf
    http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24593.pdf

In userspace microbenchmarks on a core2 system, fence instructions range
anywhere from around 15 cycles to 50, which may not be totally
insignificant in performance critical paths (code size will go down
too).

However the primary motivation for this is to have the canonical barrier
implementation for x86 architecture.

smp_rmb on buggy pentium pros remains a locked op, which is apparently
required.

Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/asm-x86/system_32.h
include/asm-x86/system_64.h

index 8b15bd3057c9b3c4c5ce844e35638396048ab46e..e7e5d426fef58c2b6892fea59c341528d827afaf 100644 (file)
@@ -274,7 +274,11 @@ static inline unsigned long get_limit(unsigned long segment)
 
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
-#define smp_rmb()      rmb()
+#ifdef CONFIG_X86_PPRO_FENCE
+# define smp_rmb()     rmb()
+#else
+# define smp_rmb()     barrier()
+#endif
 #ifdef CONFIG_X86_OOSTORE
 # define smp_wmb()     wmb()
 #else
index eff730b1192682ca85875e909dda13bb1f7e49d9..5022aecc333d7bfe6b24037b3927f15e745e4d7a 100644 (file)
@@ -141,8 +141,8 @@ static inline void write_cr8(unsigned long val)
 
 #ifdef CONFIG_SMP
 #define smp_mb()       mb()
-#define smp_rmb()      rmb()
-#define smp_wmb()      wmb()
+#define smp_rmb()      barrier()
+#define smp_wmb()      barrier()
 #define smp_read_barrier_depends()     do {} while(0)
 #else
 #define smp_mb()       barrier()