| From 2425ce84026c385b73ae72039f90d042d49e0394 Mon Sep 17 00:00:00 2001 |
| From: Mikulas Patocka <mpatocka@redhat.com> |
| Date: Thu, 8 May 2014 15:51:37 -0400 |
| Subject: metag: fix memory barriers |
| |
| From: Mikulas Patocka <mpatocka@redhat.com> |
| |
| 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> |
| |
| --- |
| arch/metag/include/asm/barrier.h | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- 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() |