aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/barrier.h
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2010-01-08 20:17:44 -0500
committerRalf Baechle <ralf@linux-mips.org>2010-02-27 06:53:06 -0500
commit6b07d38aaa520cee922fadfeaf90c97faf217045 (patch)
tree3d68d10c95ed7d87fd1692448e3903b801b40e94 /arch/mips/include/asm/barrier.h
parentf252ffd50c97dae87b45f1dbad24f71358ccfbd6 (diff)
MIPS: Octeon: Use optimized memory barrier primitives.
In order to achieve correct synchronization semantics, the Octeon port had defined CONFIG_WEAK_REORDERING_BEYOND_LLSC. This resulted in code that looks like: sync ll ... . . . sc ... . . sync The second SYNC was redundant, but harmless. Octeon has a SYNCW instruction that acts as a write-memory-barrier (due to an erratum in some parts two SYNCW are used). It is much faster than SYNC because it imposes ordering on the writes, but doesn't otherwise stall the execution pipeline. On Octeon, SYNC stalls execution until all preceeding writes are committed to the coherent memory system. Using: syncw;syncw ll . . . sc . . Has identical semantics to the first sequence, but is much faster. The SYNCW orders the writes, and the SC will not complete successfully until the write is committed to the coherent memory system. So at the end all preceeding writes have been committed. Since Octeon does not do speculative reads, this functions as a full barrier. The patch removes CONFIG_WEAK_REORDERING_BEYOND_LLSC, and substitutes SYNCW for SYNC in write-memory-barriers. Signed-off-by: David Daney <ddaney@caviumnetworks.com> To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/850/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/include/asm/barrier.h')
-rw-r--r--arch/mips/include/asm/barrier.h43
1 files changed, 31 insertions, 12 deletions
diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
index 1a5a51c3e96f..a2670a239e0c 100644
--- a/arch/mips/include/asm/barrier.h
+++ b/arch/mips/include/asm/barrier.h
@@ -88,12 +88,20 @@
88 : /* no output */ \ 88 : /* no output */ \
89 : "m" (*(int *)CKSEG1) \ 89 : "m" (*(int *)CKSEG1) \
90 : "memory") 90 : "memory")
91 91#ifdef CONFIG_CPU_CAVIUM_OCTEON
92#define fast_wmb() __sync() 92# define OCTEON_SYNCW_STR ".set push\n.set arch=octeon\nsyncw\nsyncw\n.set pop\n"
93#define fast_rmb() __sync() 93# define __syncw() __asm__ __volatile__(OCTEON_SYNCW_STR : : : "memory")
94#define fast_mb() __sync() 94
95#ifdef CONFIG_SGI_IP28 95# define fast_wmb() __syncw()
96#define fast_iob() \ 96# define fast_rmb() barrier()
97# define fast_mb() __sync()
98# define fast_iob() do { } while (0)
99#else /* ! CONFIG_CPU_CAVIUM_OCTEON */
100# define fast_wmb() __sync()
101# define fast_rmb() __sync()
102# define fast_mb() __sync()
103# ifdef CONFIG_SGI_IP28
104# define fast_iob() \
97 __asm__ __volatile__( \ 105 __asm__ __volatile__( \
98 ".set push\n\t" \ 106 ".set push\n\t" \
99 ".set noreorder\n\t" \ 107 ".set noreorder\n\t" \
@@ -104,13 +112,14 @@
104 : /* no output */ \ 112 : /* no output */ \
105 : "m" (*(int *)CKSEG1ADDR(0x1fa00004)) \ 113 : "m" (*(int *)CKSEG1ADDR(0x1fa00004)) \
106 : "memory") 114 : "memory")
107#else 115# else
108#define fast_iob() \ 116# define fast_iob() \
109 do { \ 117 do { \
110 __sync(); \ 118 __sync(); \
111 __fast_iob(); \ 119 __fast_iob(); \
112 } while (0) 120 } while (0)
113#endif 121# endif
122#endif /* CONFIG_CPU_CAVIUM_OCTEON */
114 123
115#ifdef CONFIG_CPU_HAS_WB 124#ifdef CONFIG_CPU_HAS_WB
116 125
@@ -131,9 +140,15 @@
131#endif /* !CONFIG_CPU_HAS_WB */ 140#endif /* !CONFIG_CPU_HAS_WB */
132 141
133#if defined(CONFIG_WEAK_ORDERING) && defined(CONFIG_SMP) 142#if defined(CONFIG_WEAK_ORDERING) && defined(CONFIG_SMP)
134#define smp_mb() __asm__ __volatile__("sync" : : :"memory") 143# ifdef CONFIG_CPU_CAVIUM_OCTEON
135#define smp_rmb() __asm__ __volatile__("sync" : : :"memory") 144# define smp_mb() __sync()
136#define smp_wmb() __asm__ __volatile__("sync" : : :"memory") 145# define smp_rmb() barrier()
146# define smp_wmb() __syncw()
147# else
148# define smp_mb() __asm__ __volatile__("sync" : : :"memory")
149# define smp_rmb() __asm__ __volatile__("sync" : : :"memory")
150# define smp_wmb() __asm__ __volatile__("sync" : : :"memory")
151# endif
137#else 152#else
138#define smp_mb() barrier() 153#define smp_mb() barrier()
139#define smp_rmb() barrier() 154#define smp_rmb() barrier()
@@ -151,6 +166,10 @@
151 166
152#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") 167#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
153 168
169#ifdef CONFIG_CPU_CAVIUM_OCTEON
170#define smp_mb__before_llsc() smp_wmb()
171#else
154#define smp_mb__before_llsc() smp_llsc_mb() 172#define smp_mb__before_llsc() smp_llsc_mb()
173#endif
155 174
156#endif /* __ASM_BARRIER_H */ 175#endif /* __ASM_BARRIER_H */