diff options
author | kib <kib@FreeBSD.org> | 2015-11-24 09:13:21 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2015-11-24 09:13:21 +0000 |
commit | 07726f427335a000beab31d99b2798ca3e8a60c8 (patch) | |
tree | 7bd866175dc6bb84bb3d290feccb37557b488d0e | |
parent | 8b511cec83ea09d8517aeb4834bd6d6fd45acad1 (diff) | |
download | FreeBSD-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
-rw-r--r-- | sys/powerpc/include/atomic.h | 35 |
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 |