* [ltt-dev] [URCU PATCH] caa: do not generate code for rmb/wmb on x86_64, rmb on i686
@ 2011-09-05 11:27 Paolo Bonzini
2011-09-05 15:12 ` Mathieu Desnoyers
[not found] ` <BLU0-SMTP648D3439671501BF3EC1AE961D0@phx.gbl>
0 siblings, 2 replies; 4+ messages in thread
From: Paolo Bonzini @ 2011-09-05 11:27 UTC (permalink / raw)
In userspace we can assume no accesses to write-combining memory occur,
and also that there are no non-temporal load/stores (people would presumably
write those with assembly or intrinsics and put appropriate lfence/sfence
manually). So rmb and wmb are no-ops on x86.
But IDT chips are an exception, so keep wmb on 32-bit and document better
the rationale.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
urcu/arch/x86.h | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/urcu/arch/x86.h b/urcu/arch/x86.h
index 9e5411f..d25f13d 100644
--- a/urcu/arch/x86.h
+++ b/urcu/arch/x86.h
@@ -33,15 +33,19 @@ extern "C" {
#ifdef CONFIG_RCU_HAVE_FENCE
#define cmm_mb() asm volatile("mfence":::"memory")
-#define cmm_rmb() asm volatile("lfence":::"memory")
-#define cmm_wmb() asm volatile("sfence"::: "memory")
+#define cmm_rmb() asm volatile("":::"memory")
+#define cmm_wmb() asm volatile(""::: "memory")
#else
/*
- * Some non-Intel clones support out of order store. cmm_wmb() ceases to be a
- * nop for these.
+ * IDT WinChip supports weak store ordering, and the kernel may enable it
+ * under our feet; cmm_wmb() ceases to be a nop for these processors.
+ *
+ * The same would hold for cmm_rmb() on some old PentiumPro multiprocessor
+ * systems that have an errata, but the Linux kernel says that "Even distro
+ * kernels should think twice before enabling this".
*/
#define cmm_mb() asm volatile("lock; addl $0,0(%%esp)":::"memory")
-#define cmm_rmb() asm volatile("lock; addl $0,0(%%esp)":::"memory")
+#define cmm_rmb() asm volatile("":::"memory")
#define cmm_wmb() asm volatile("lock; addl $0,0(%%esp)"::: "memory")
#endif
--
1.7.6
^ permalink raw reply [flat|nested] 4+ messages in thread* [ltt-dev] [URCU PATCH] caa: do not generate code for rmb/wmb on x86_64, rmb on i686 2011-09-05 11:27 [ltt-dev] [URCU PATCH] caa: do not generate code for rmb/wmb on x86_64, rmb on i686 Paolo Bonzini @ 2011-09-05 15:12 ` Mathieu Desnoyers [not found] ` <BLU0-SMTP648D3439671501BF3EC1AE961D0@phx.gbl> 1 sibling, 0 replies; 4+ messages in thread From: Mathieu Desnoyers @ 2011-09-05 15:12 UTC (permalink / raw) Hi Paolo, * Paolo Bonzini (pbonzini at redhat.com) wrote: > In userspace we can assume no accesses to write-combining memory occur, > and also that there are no non-temporal load/stores (people would presumably > write those with assembly or intrinsics and put appropriate lfence/sfence > manually). So rmb and wmb are no-ops on x86. What about memory barriers for DMA with devices ? For these, we might want to define cmm_wmb/rmb and cmm_smp_wmb/rmb differently (keep the fences for DMA accesses). So people who want to use memory barriers for non-temporal load/stores could use the cmm_wmb/rmb variants too. > > But IDT chips are an exception, so keep wmb on 32-bit and document better > the rationale. > > Signed-off-by: Paolo Bonzini <pbonzini at redhat.com> > --- > urcu/arch/x86.h | 14 +++++++++----- > 1 files changed, 9 insertions(+), 5 deletions(-) > > diff --git a/urcu/arch/x86.h b/urcu/arch/x86.h > index 9e5411f..d25f13d 100644 > --- a/urcu/arch/x86.h > +++ b/urcu/arch/x86.h > @@ -33,15 +33,19 @@ extern "C" { > > #ifdef CONFIG_RCU_HAVE_FENCE > #define cmm_mb() asm volatile("mfence":::"memory") > -#define cmm_rmb() asm volatile("lfence":::"memory") > -#define cmm_wmb() asm volatile("sfence"::: "memory") > +#define cmm_rmb() asm volatile("":::"memory") > +#define cmm_wmb() asm volatile(""::: "memory") > #else > /* > - * Some non-Intel clones support out of order store. cmm_wmb() ceases to be a > - * nop for these. > + * IDT WinChip supports weak store ordering, and the kernel may enable it > + * under our feet; cmm_wmb() ceases to be a nop for these processors. > + * > + * The same would hold for cmm_rmb() on some old PentiumPro multiprocessor > + * systems that have an errata, but the Linux kernel says that "Even distro > + * kernels should think twice before enabling this". Maybe we should have configure options --without-x86-ppro-support and --without-x86-idt-winchip-support for this ? I really want the default to be bullet-proof. So deactivating support for these specific architectures on a per-distro basis would make more sense. Thanks, Mathieu > */ > #define cmm_mb() asm volatile("lock; addl $0,0(%%esp)":::"memory") > -#define cmm_rmb() asm volatile("lock; addl $0,0(%%esp)":::"memory") > +#define cmm_rmb() asm volatile("":::"memory") > #define cmm_wmb() asm volatile("lock; addl $0,0(%%esp)"::: "memory") > #endif -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <BLU0-SMTP648D3439671501BF3EC1AE961D0@phx.gbl>]
* [ltt-dev] [URCU PATCH] caa: do not generate code for rmb/wmb on x86_64, rmb on i686 [not found] ` <BLU0-SMTP648D3439671501BF3EC1AE961D0@phx.gbl> @ 2011-09-05 15:15 ` Paolo Bonzini 2011-09-05 15:32 ` Mathieu Desnoyers 0 siblings, 1 reply; 4+ messages in thread From: Paolo Bonzini @ 2011-09-05 15:15 UTC (permalink / raw) On 09/05/2011 05:12 PM, Mathieu Desnoyers wrote: >> In userspace we can assume no accesses to write-combining memory occur, >> > and also that there are no non-temporal load/stores (people would presumably >> > write those with assembly or intrinsics and put appropriate lfence/sfence >> > manually). So rmb and wmb are no-ops on x86. > > What about memory barriers for DMA with devices ? For these, we might > want to define cmm_wmb/rmb and cmm_smp_wmb/rmb differently (keep the > fences for DMA accesses). Yes, splitting wmb/rmb and smp_wmb/rmb makes sense. Paolo ^ permalink raw reply [flat|nested] 4+ messages in thread
* [ltt-dev] [URCU PATCH] caa: do not generate code for rmb/wmb on x86_64, rmb on i686 2011-09-05 15:15 ` Paolo Bonzini @ 2011-09-05 15:32 ` Mathieu Desnoyers 0 siblings, 0 replies; 4+ messages in thread From: Mathieu Desnoyers @ 2011-09-05 15:32 UTC (permalink / raw) * Paolo Bonzini (pbonzini at redhat.com) wrote: > On 09/05/2011 05:12 PM, Mathieu Desnoyers wrote: >>> In userspace we can assume no accesses to write-combining memory occur, >>> > and also that there are no non-temporal load/stores (people would presumably >>> > write those with assembly or intrinsics and put appropriate lfence/sfence >>> > manually). So rmb and wmb are no-ops on x86. >> >> What about memory barriers for DMA with devices ? For these, we might >> want to define cmm_wmb/rmb and cmm_smp_wmb/rmb differently (keep the >> fences for DMA accesses). > > Yes, splitting wmb/rmb and smp_wmb/rmb makes sense. Quoting: www.rdrop.com/users/paulmck/scalability/paper/ordering.2007.09.19a.pdf "AMD64 AMD64 is compatible with x86, and has recently updated its memory model [1] to enforce the tighter ordering that actual implementations have provided for some time. The AMD64 implementation of the Linux smp mb() primitive is mfence, smp rmb() is lfence, and smp wmb() is sfence. In theory, these might be relaxed, but any such relaxation must take SSE and 3DNOW instructions into account." -> So I think we should document that cmm_wmb/rmb/mb take care of SSE, 3DNOW and DMA accesses, but cmm_smp_*mb does not. "x86 Since the x86 CPUs provide ?process ordering? so that all CPUs agree on the order of a given CPU?s writes to memory, the smp wmb() primitive is a no-op for the CPU [7]. However, a compiler directive is required to prevent the compiler from performing optimizations that would result in reordering across the smp wmb() primitive. On the other hand, x86 CPUs have traditionally given no ordering guarantees for loads, so the smp mb() and smp rmb() primitives expand to lock;addl. This atomic instruction acts as a barrier to both loads and stores. More recently, Intel has published a memory model for x86 [8]. It turns out that Intel?s actual CPUs enforced tighter ordering than was claimed in the previous specifications, so this model is in effect simply mandating the earlier de-facto behavior. However, note that some SSE instructions are weakly ordered (clflush and non-temporal move instructions [6]). CPUs that have SSE can use mfence for smp mb(), lfence for smp rmb(), and sfence for smp wmb(). A few versions of the x86 CPU have a mode bit that enables out-of-order stores, and for these CPUs, smp wmb() must also be defined to be lock;addl. Although many older x86 implementations accommodated self-modifying code without the need for any special instructions, newer revisions of the x86 architecture no longer require x86 CPUs to be so accommodating. Interestingly enough, this relaxation comes just in time to inconvenience JIT implementors." -> So for Intel x86, it would make sense to document that cmm_rmb/wmb/mb take care of SSE, DMA accesses, non-temporal moves and clflush. We should also document that the "smp" variants of those primitives offer no guarantee for these cases. None of our fences offer ordering guarantees wrt prefetch instructions. Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-09-05 15:32 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-05 11:27 [ltt-dev] [URCU PATCH] caa: do not generate code for rmb/wmb on x86_64, rmb on i686 Paolo Bonzini
2011-09-05 15:12 ` Mathieu Desnoyers
[not found] ` <BLU0-SMTP648D3439671501BF3EC1AE961D0@phx.gbl>
2011-09-05 15:15 ` Paolo Bonzini
2011-09-05 15:32 ` Mathieu Desnoyers
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox