From d475f3f47a0427dfee483cecf9a7e9109e991423 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Fri, 21 Oct 2005 22:06:15 +0400 Subject: [PATCH] alpha: additional smp barriers As stated in Documentation/atomic_ops.txt, atomic functions returning values must have the memory barriers both before and after the operation. Thanks to DaveM for pointing that out. Signed-off-by: Ivan Kokshaysky Signed-off-by: Linus Torvalds --- include/asm-alpha/atomic.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'include/asm-alpha') diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h index 1b383e3cb68c..0b40bad00289 100644 --- a/include/asm-alpha/atomic.h +++ b/include/asm-alpha/atomic.h @@ -100,18 +100,19 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v) static __inline__ long atomic_add_return(int i, atomic_t * v) { long temp, result; + smp_mb(); __asm__ __volatile__( "1: ldl_l %0,%1\n" " addl %0,%3,%2\n" " addl %0,%3,%0\n" " stl_c %0,%1\n" " beq %0,2f\n" - " mb\n" ".subsection 2\n" "2: br 1b\n" ".previous" :"=&r" (temp), "=m" (v->counter), "=&r" (result) :"Ir" (i), "m" (v->counter) : "memory"); + smp_mb(); return result; } @@ -120,54 +121,57 @@ static __inline__ long atomic_add_return(int i, atomic_t * v) static __inline__ long atomic64_add_return(long i, atomic64_t * v) { long temp, result; + smp_mb(); __asm__ __volatile__( "1: ldq_l %0,%1\n" " addq %0,%3,%2\n" " addq %0,%3,%0\n" " stq_c %0,%1\n" " beq %0,2f\n" - " mb\n" ".subsection 2\n" "2: br 1b\n" ".previous" :"=&r" (temp), "=m" (v->counter), "=&r" (result) :"Ir" (i), "m" (v->counter) : "memory"); + smp_mb(); return result; } static __inline__ long atomic_sub_return(int i, atomic_t * v) { long temp, result; + smp_mb(); __asm__ __volatile__( "1: ldl_l %0,%1\n" " subl %0,%3,%2\n" " subl %0,%3,%0\n" " stl_c %0,%1\n" " beq %0,2f\n" - " mb\n" ".subsection 2\n" "2: br 1b\n" ".previous" :"=&r" (temp), "=m" (v->counter), "=&r" (result) :"Ir" (i), "m" (v->counter) : "memory"); + smp_mb(); return result; } static __inline__ long atomic64_sub_return(long i, atomic64_t * v) { long temp, result; + smp_mb(); __asm__ __volatile__( "1: ldq_l %0,%1\n" " subq %0,%3,%2\n" " subq %0,%3,%0\n" " stq_c %0,%1\n" " beq %0,2f\n" - " mb\n" ".subsection 2\n" "2: br 1b\n" ".previous" :"=&r" (temp), "=m" (v->counter), "=&r" (result) :"Ir" (i), "m" (v->counter) : "memory"); + smp_mb(); return result; } -- cgit v1.2.2 From 0db9ae4a79381a5a3d272ccb51851c48c4bcbb6d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 24 Oct 2005 23:05:58 -0700 Subject: [PATCH] alpha: atomic dependency fix My alpha build is exploding because asm/atomic.h now needs smb_mb(), which is over in the (not included) system.h. I fear what will happen if I include system.h into atomic.h, so let's put the barriers into their own header file. Cc: Richard Henderson Cc: Ivan Kokshaysky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-alpha/atomic.h | 2 ++ include/asm-alpha/barrier.h | 34 ++++++++++++++++++++++++++++++++++ include/asm-alpha/system.h | 31 +------------------------------ 3 files changed, 37 insertions(+), 30 deletions(-) create mode 100644 include/asm-alpha/barrier.h (limited to 'include/asm-alpha') diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h index 0b40bad00289..20ac3d95ecd9 100644 --- a/include/asm-alpha/atomic.h +++ b/include/asm-alpha/atomic.h @@ -1,6 +1,8 @@ #ifndef _ALPHA_ATOMIC_H #define _ALPHA_ATOMIC_H +#include + /* * Atomic operations that C can't guarantee us. Useful for * resource counting etc... diff --git a/include/asm-alpha/barrier.h b/include/asm-alpha/barrier.h new file mode 100644 index 000000000000..229c83fe77cb --- /dev/null +++ b/include/asm-alpha/barrier.h @@ -0,0 +1,34 @@ +#ifndef __BARRIER_H +#define __BARRIER_H + +#define mb() \ +__asm__ __volatile__("mb": : :"memory") + +#define rmb() \ +__asm__ __volatile__("mb": : :"memory") + +#define wmb() \ +__asm__ __volatile__("wmb": : :"memory") + +#define read_barrier_depends() \ +__asm__ __volatile__("mb": : :"memory") + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#define smp_rmb() rmb() +#define smp_wmb() wmb() +#define smp_read_barrier_depends() read_barrier_depends() +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() barrier() +#endif + +#define set_mb(var, value) \ +do { var = value; mb(); } while (0) + +#define set_wmb(var, value) \ +do { var = value; wmb(); } while (0) + +#endif /* __BARRIER_H */ diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index bdb4d66418f1..050e86d12891 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -4,6 +4,7 @@ #include #include #include +#include /* * System defines.. Note that this is included both from .c and .S @@ -139,36 +140,6 @@ extern void halt(void) __attribute__((noreturn)); struct task_struct; extern struct task_struct *alpha_switch_to(unsigned long, struct task_struct*); -#define mb() \ -__asm__ __volatile__("mb": : :"memory") - -#define rmb() \ -__asm__ __volatile__("mb": : :"memory") - -#define wmb() \ -__asm__ __volatile__("wmb": : :"memory") - -#define read_barrier_depends() \ -__asm__ __volatile__("mb": : :"memory") - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() barrier() -#endif - -#define set_mb(var, value) \ -do { var = value; mb(); } while (0) - -#define set_wmb(var, value) \ -do { var = value; wmb(); } while (0) - #define imb() \ __asm__ __volatile__ ("call_pal %0 #imb" : : "i" (PAL_imb) : "memory") -- cgit v1.2.2