summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/include
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-11-24 09:13:21 +0000
committerkib <kib@FreeBSD.org>2015-11-24 09:13:21 +0000
commit07726f427335a000beab31d99b2798ca3e8a60c8 (patch)
tree7bd866175dc6bb84bb3d290feccb37557b488d0e /sys/powerpc/include
parent8b511cec83ea09d8517aeb4834bd6d6fd45acad1 (diff)
downloadFreeBSD-src-07726f427335a000beab31d99b2798ca3e8a60c8.zip
FreeBSD-src-07726f427335a000beab31d99b2798ca3e8a60c8.tar.gz
On PowerPC 64bit, the linux-compat mb() definition is implemented with
lwsync instruction, which does not provide Store/Load barrier. Fix this by using "full" sync barrier for mb(). atomic_store_rel() does not need full barrier, change mb() call there to the lwsync instruction if not hitting the known CPU erratas (i.e. on 32bit). Provide powerpc_lwsync() helper to isolate the lwsync/sync compile time selection, and use it in atomic_store_rel() and several other places which duplicate the code. Noted by: alc Reviewed and tested by: nwhitehorn Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/powerpc/include')
-rw-r--r--sys/powerpc/include/atomic.h35
1 files changed, 17 insertions, 18 deletions
diff --git a/sys/powerpc/include/atomic.h b/sys/powerpc/include/atomic.h
index 92fe279..c4db5ff 100644
--- a/sys/powerpc/include/atomic.h
+++ b/sys/powerpc/include/atomic.h
@@ -48,7 +48,7 @@
*/
#ifdef __powerpc64__
-#define mb() __asm __volatile("lwsync" : : : "memory")
+#define mb() __asm __volatile("sync" : : : "memory")
#define rmb() __asm __volatile("lwsync" : : : "memory")
#define wmb() __asm __volatile("lwsync" : : : "memory")
#define __ATOMIC_REL() __asm __volatile("lwsync" : : : "memory")
@@ -61,6 +61,17 @@
#define __ATOMIC_ACQ() __asm __volatile("isync" : : : "memory")
#endif
+static __inline void
+powerpc_lwsync(void)
+{
+
+#ifdef __powerpc64__
+ __asm __volatile("lwsync" : : : "memory");
+#else
+ __asm __volatile("sync" : : : "memory");
+#endif
+}
+
/*
* atomic_add(p, v)
* { *p += v; }
@@ -506,7 +517,8 @@ atomic_load_acq_##TYPE(volatile u_##TYPE *p) \
static __inline void \
atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) \
{ \
- mb(); \
+ \
+ powerpc_lwsync(); \
*p = v; \
}
@@ -734,34 +746,21 @@ static __inline void
atomic_thread_fence_acq(void)
{
- /* See above comment about lwsync being broken on Book-E. */
-#ifdef __powerpc64__
- __asm __volatile("lwsync" : : : "memory");
-#else
- __asm __volatile("sync" : : : "memory");
-#endif
+ powerpc_lwsync();
}
static __inline void
atomic_thread_fence_rel(void)
{
-#ifdef __powerpc64__
- __asm __volatile("lwsync" : : : "memory");
-#else
- __asm __volatile("sync" : : : "memory");
-#endif
+ powerpc_lwsync();
}
static __inline void
atomic_thread_fence_acq_rel(void)
{
-#ifdef __powerpc64__
- __asm __volatile("lwsync" : : : "memory");
-#else
- __asm __volatile("sync" : : : "memory");
-#endif
+ powerpc_lwsync();
}
static __inline void
OpenPOWER on IntegriCloud