diff options
Diffstat (limited to 'arch/arm64/include/asm/cmpxchg.h')
| -rw-r--r-- | arch/arm64/include/asm/cmpxchg.h | 54 | 
1 files changed, 34 insertions, 20 deletions
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h index 8a8ce0e73a3..ddb9d783055 100644 --- a/arch/arm64/include/asm/cmpxchg.h +++ b/arch/arm64/include/asm/cmpxchg.h @@ -29,49 +29,55 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size  	switch (size) {  	case 1:  		asm volatile("//	__xchg1\n" -		"1:	ldaxrb	%w0, %2\n" +		"1:	ldxrb	%w0, %2\n"  		"	stlxrb	%w1, %w3, %2\n"  		"	cbnz	%w1, 1b\n"  			: "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr)  			: "r" (x) -			: "cc", "memory"); +			: "memory");  		break;  	case 2:  		asm volatile("//	__xchg2\n" -		"1:	ldaxrh	%w0, %2\n" +		"1:	ldxrh	%w0, %2\n"  		"	stlxrh	%w1, %w3, %2\n"  		"	cbnz	%w1, 1b\n"  			: "=&r" (ret), "=&r" (tmp), "+Q" (*(u16 *)ptr)  			: "r" (x) -			: "cc", "memory"); +			: "memory");  		break;  	case 4:  		asm volatile("//	__xchg4\n" -		"1:	ldaxr	%w0, %2\n" +		"1:	ldxr	%w0, %2\n"  		"	stlxr	%w1, %w3, %2\n"  		"	cbnz	%w1, 1b\n"  			: "=&r" (ret), "=&r" (tmp), "+Q" (*(u32 *)ptr)  			: "r" (x) -			: "cc", "memory"); +			: "memory");  		break;  	case 8:  		asm volatile("//	__xchg8\n" -		"1:	ldaxr	%0, %2\n" +		"1:	ldxr	%0, %2\n"  		"	stlxr	%w1, %3, %2\n"  		"	cbnz	%w1, 1b\n"  			: "=&r" (ret), "=&r" (tmp), "+Q" (*(u64 *)ptr)  			: "r" (x) -			: "cc", "memory"); +			: "memory");  		break;  	default:  		BUILD_BUG();  	} +	smp_mb();  	return ret;  }  #define xchg(ptr,x) \ -	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +({ \ +	__typeof__(*(ptr)) __ret; \ +	__ret = (__typeof__(*(ptr))) \ +		__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))); \ +	__ret; \ +})  static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,  				      unsigned long new, int size) @@ -158,19 +164,27 @@ static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,  	return ret;  } -#define cmpxchg(ptr,o,n)						\ -	((__typeof__(*(ptr)))__cmpxchg_mb((ptr),			\ -					  (unsigned long)(o),		\ -					  (unsigned long)(n),		\ -					  sizeof(*(ptr)))) - -#define cmpxchg_local(ptr,o,n)						\ -	((__typeof__(*(ptr)))__cmpxchg((ptr),				\ -				       (unsigned long)(o),		\ -				       (unsigned long)(n),		\ -				       sizeof(*(ptr)))) +#define cmpxchg(ptr, o, n) \ +({ \ +	__typeof__(*(ptr)) __ret; \ +	__ret = (__typeof__(*(ptr))) \ +		__cmpxchg_mb((ptr), (unsigned long)(o), (unsigned long)(n), \ +			     sizeof(*(ptr))); \ +	__ret; \ +}) + +#define cmpxchg_local(ptr, o, n) \ +({ \ +	__typeof__(*(ptr)) __ret; \ +	__ret = (__typeof__(*(ptr))) \ +		__cmpxchg((ptr), (unsigned long)(o), \ +			  (unsigned long)(n), sizeof(*(ptr))); \ +	__ret; \ +})  #define cmpxchg64(ptr,o,n)		cmpxchg((ptr),(o),(n))  #define cmpxchg64_local(ptr,o,n)	cmpxchg_local((ptr),(o),(n)) +#define cmpxchg64_relaxed(ptr,o,n)	cmpxchg_local((ptr),(o),(n)) +  #endif	/* __ASM_CMPXCHG_H */  | 
