summaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/atomic.h
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2019-06-13 15:43:19 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-10-07 18:59:27 +0200
commit57e4c0e0efce23f4bc82c4adcfa4a6754e61486a (patch)
tree9452c3c6db3327f433f80721566833cc9b586290 /arch/mips/include/asm/atomic.h
parent11daaf5c38f2a53c93ce986c82d2ba201b09dd1c (diff)
downloadlinux-stable-57e4c0e0efce23f4bc82c4adcfa4a6754e61486a.tar.gz
linux-stable-57e4c0e0efce23f4bc82c4adcfa4a6754e61486a.tar.bz2
linux-stable-57e4c0e0efce23f4bc82c4adcfa4a6754e61486a.zip
mips/atomic: Fix loongson_llsc_mb() wreckage
[ Upstream commit 1c6c1ca318585f1096d4d04bc722297c85e9fb8a ] The comment describing the loongson_llsc_mb() reorder case doesn't make any sense what so ever. Instruction re-ordering is not an SMP artifact, but rather a CPU local phenomenon. Clarify the comment by explaining that these issue cause a coherence fail. For the branch speculation case; if futex_atomic_cmpxchg_inatomic() needs one at the bne branch target, then surely the normal __cmpxch_asm() implementation does too. We cannot rely on the barriers from cmpxchg() because cmpxchg_local() is implemented with the same macro, and branch prediction and speculation are, too, CPU local. Fixes: e02e07e3127d ("MIPS: Loongson: Introduce and use loongson_llsc_mb()") Cc: Huacai Chen <chenhc@lemote.com> Cc: Huang Pei <huangpei@loongson.cn> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Paul Burton <paul.burton@mips.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'arch/mips/include/asm/atomic.h')
-rw-r--r--arch/mips/include/asm/atomic.h5
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index 94096299fc56..c85405afba5e 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -193,6 +193,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
if (kernel_uses_llsc) {
int temp;
+ loongson_llsc_mb();
__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_LEVEL" \n"
@@ -200,12 +201,12 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
" .set pop \n"
" subu %0, %1, %3 \n"
" move %1, %0 \n"
- " bltz %0, 1f \n"
+ " bltz %0, 2f \n"
" .set push \n"
" .set "MIPS_ISA_LEVEL" \n"
" sc %1, %2 \n"
"\t" __scbeqz " %1, 1b \n"
- "1: \n"
+ "2: \n"
" .set pop \n"
: "=&r" (result), "=&r" (temp),
"+" GCC_OFF_SMALL_ASM() (v->counter)