aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2014-05-08 15:51:37 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-07 13:25:37 -0700
commit44563045712ee4f385b5f3814d69fc73b5f22288 (patch)
tree2e6bcadf007ed599527b1c45a62ddececd7c5fd6
parentaece7dc95409f8934281954a7e82ddf55b765913 (diff)
downloadlinux-linaro-stable-44563045712ee4f385b5f3814d69fc73b5f22288.tar.gz
metag: fix memory barriers
commit 2425ce84026c385b73ae72039f90d042d49e0394 upstream. Volatile access doesn't really imply the compiler barrier. Volatile access is only ordered with respect to other volatile accesses, it isn't ordered with respect to general memory accesses. Gcc may reorder memory accesses around volatile access, as we can see in this simple example (if we compile it with optimization, both increments of *b will be collapsed to just one): void fn(volatile int *a, long *b) { (*b)++; *a = 10; (*b)++; } Consequently, we need the compiler barrier after a write to the volatile variable, to make sure that the compiler doesn't reorder the volatile write with something else. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Acked-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: James Hogan <james.hogan@imgtec.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/metag/include/asm/barrier.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/arch/metag/include/asm/barrier.h b/arch/metag/include/asm/barrier.h
index c90bfc6bf648..e355a4c10968 100644
--- a/arch/metag/include/asm/barrier.h
+++ b/arch/metag/include/asm/barrier.h
@@ -15,6 +15,7 @@ static inline void wr_fence(void)
volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_FENCE;
barrier();
*flushptr = 0;
+ barrier();
}
#else /* CONFIG_METAG_META21 */
@@ -35,6 +36,7 @@ static inline void wr_fence(void)
*flushptr = 0;
*flushptr = 0;
*flushptr = 0;
+ barrier();
}
#endif /* !CONFIG_METAG_META21 */
@@ -68,6 +70,7 @@ static inline void fence(void)
volatile int *flushptr = (volatile int *) LINSYSEVENT_WR_ATOMIC_UNLOCK;
barrier();
*flushptr = 0;
+ barrier();
}
#define smp_mb() fence()
#define smp_rmb() fence()