|
|
9ae3a8 |
From d37475eb567b61ce6a18f9fcbf35eb929be8d99f Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
Date: Fri, 19 Jun 2015 10:45:29 +0200
|
|
|
9ae3a8 |
Subject: [PATCH] atomics: add explicit compiler fence in __atomic memory
|
|
|
9ae3a8 |
barriers
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Message-id: <1434710730-26183-1-git-send-email-pbonzini@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 66333
|
|
|
9ae3a8 |
O-Subject: [RHEL7.2/7.1.z qemu-kvm PATCH] atomics: add explicit compiler fence in __atomic memory barriers
|
|
|
9ae3a8 |
Bugzilla: 1142857
|
|
|
9ae3a8 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Bugzilla: 1142857 (aka 8*10^6/7)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Brew build: 9393725
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
__atomic_thread_fence does not include a compiler barrier; in the
|
|
|
9ae3a8 |
C++11 memory model, fences take effect in combination with other
|
|
|
9ae3a8 |
atomic operations. GCC implements this by making __atomic_load and
|
|
|
9ae3a8 |
__atomic_store access memory as if the pointer was volatile, and
|
|
|
9ae3a8 |
leaves no trace whatsoever of acquire and release fences in the
|
|
|
9ae3a8 |
compiler's intermediate representation.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
In QEMU, we want memory barriers to act on all memory, but at the same
|
|
|
9ae3a8 |
time we would like to use __atomic_thread_fence for portability reasons.
|
|
|
9ae3a8 |
Add compiler barriers manually around the __atomic_thread_fence.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Thanks to Uli and Kevin for analyzing this bug!
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Message-Id: <1433334080-14912-1-git-send-email-pbonzini@redhat.com>
|
|
|
9ae3a8 |
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit 3bbf572345c65813f86a8fc434ea1b23beb08e16)
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
include/qemu/atomic.h | 12 +++++++++---
|
|
|
9ae3a8 |
1 file changed, 9 insertions(+), 3 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
|
|
|
9ae3a8 |
index 0aa8913..690d0d6 100644
|
|
|
9ae3a8 |
--- a/include/qemu/atomic.h
|
|
|
9ae3a8 |
+++ b/include/qemu/atomic.h
|
|
|
9ae3a8 |
@@ -99,7 +99,13 @@
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
#ifndef smp_wmb
|
|
|
9ae3a8 |
#ifdef __ATOMIC_RELEASE
|
|
|
9ae3a8 |
-#define smp_wmb() __atomic_thread_fence(__ATOMIC_RELEASE)
|
|
|
9ae3a8 |
+/* __atomic_thread_fence does not include a compiler barrier; instead,
|
|
|
9ae3a8 |
+ * the barrier is part of __atomic_load/__atomic_store's "volatile-like"
|
|
|
9ae3a8 |
+ * semantics. If smp_wmb() is a no-op, absence of the barrier means that
|
|
|
9ae3a8 |
+ * the compiler is free to reorder stores on each side of the barrier.
|
|
|
9ae3a8 |
+ * Add one here, and similarly in smp_rmb() and smp_read_barrier_depends().
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+#define smp_wmb() ({ barrier(); __atomic_thread_fence(__ATOMIC_RELEASE); barrier(); })
|
|
|
9ae3a8 |
#else
|
|
|
9ae3a8 |
#define smp_wmb() __sync_synchronize()
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
@@ -107,7 +113,7 @@
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
#ifndef smp_rmb
|
|
|
9ae3a8 |
#ifdef __ATOMIC_ACQUIRE
|
|
|
9ae3a8 |
-#define smp_rmb() __atomic_thread_fence(__ATOMIC_ACQUIRE)
|
|
|
9ae3a8 |
+#define smp_rmb() ({ barrier(); __atomic_thread_fence(__ATOMIC_ACQUIRE); barrier(); })
|
|
|
9ae3a8 |
#else
|
|
|
9ae3a8 |
#define smp_rmb() __sync_synchronize()
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
@@ -115,7 +121,7 @@
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
#ifndef smp_read_barrier_depends
|
|
|
9ae3a8 |
#ifdef __ATOMIC_CONSUME
|
|
|
9ae3a8 |
-#define smp_read_barrier_depends() __atomic_thread_fence(__ATOMIC_CONSUME)
|
|
|
9ae3a8 |
+#define smp_read_barrier_depends() ({ barrier(); __atomic_thread_fence(__ATOMIC_CONSUME); barrier(); })
|
|
|
9ae3a8 |
#else
|
|
|
9ae3a8 |
#define smp_read_barrier_depends() barrier()
|
|
|
9ae3a8 |
#endif
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.8.3.1
|
|
|
9ae3a8 |
|