]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
x86: Use LOCK ADD instead of MFENCE for smp_mb()
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 21 Sep 2020 12:17:30 +0000 (13:17 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 1 Oct 2020 10:14:22 +0000 (11:14 +0100)
MFENCE is overly heavyweight for SMP semantics on WB memory, because it also
orders weaker cached writes, and flushes the WC buffers.

This technique was used as an optimisation in Java[1], and later adopted by
Linux[2] where it was measured to have a 60% performance improvement in VirtIO
benchmarks.

The stack is used because it is hot in the L1 cache, and a -4 offset is used
to avoid creating a false data dependency on live data.

For 64bit userspace, the Red Zone needs to be considered.  Use -32 to allow
for a reasonable quantity of Red Zone data, but still have a 50% chance of
hitting the same cache line as %rsp.

Fix up the 32 bit definitions in HVMLoader and libxc to avoid a false data
dependency.

[1] https://shipilev.net/blog/2014/on-the-fence-with-dependencies/
[2] https://git.kernel.org/torvalds/c/450cbdd0125cfa5d7bbf9e2a6b6961cc48d29730

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Wei Liu <wl@xen.org>
tools/firmware/hvmloader/util.h
tools/libs/ctrl/include/xenctrl.h
xen/include/asm-x86/system.h

index 31889de6349b38761de9d9f92a24415ddf9901d7..4f0baade0e6c91d4da5b3a021b8c57d0fb2947a9 100644 (file)
@@ -133,7 +133,7 @@ static inline void cpu_relax(void)
 #define barrier() asm volatile ( "" : : : "memory" )
 #define rmb()     barrier()
 #define wmb()     barrier()
-#define mb()      asm volatile ( "lock; addl $0,0(%%esp)" : : : "memory" )
+#define mb()      asm volatile ( "lock addl $0, -4(%%esp)" ::: "memory" )
 
 /*
  * Divide a 64-bit dividend by a 32-bit divisor.
index ba70bec9c4d655a19b6335407484342f221650fb..3796425e1ecafa5ff2134c5c7d3535492982989a 100644 (file)
 #define xen_barrier() asm volatile ( "" : : : "memory")
 
 #if defined(__i386__)
-#define xen_mb()  asm volatile ( "lock; addl $0,0(%%esp)" : : : "memory" )
+#define xen_mb()  asm volatile ( "lock addl $0, -4(%%esp)" ::: "memory" )
 #define xen_rmb() xen_barrier()
 #define xen_wmb() xen_barrier()
 #elif defined(__x86_64__)
-#define xen_mb()  asm volatile ( "mfence" : : : "memory")
+#define xen_mb()  asm volatile ( "lock addl $0, -32(%%rsp)" ::: "memory" )
 #define xen_rmb() xen_barrier()
 #define xen_wmb() xen_barrier()
 #elif defined(__arm__)
index 45c183bd101c015cf196ff6a6e636c9f520462bb..630909965efc9398687a1b1f128c30b7d94bc15e 100644 (file)
@@ -220,7 +220,7 @@ static always_inline unsigned long __xadd(
  *
  * Refer to the vendor system programming manuals for further details.
  */
-#define smp_mb()        mb()
+#define smp_mb()        asm volatile ( "lock addl $0, -4(%%rsp)" ::: "memory" )
 #define smp_rmb()       barrier()
 #define smp_wmb()       barrier()