cregit-Linux how code gets into the kernel

Release 4.8 arch/powerpc/include/asm/cmpxchg.h

#ifndef _ASM_POWERPC_CMPXCHG_H_

#define _ASM_POWERPC_CMPXCHG_H_

#ifdef __KERNEL__
#include <linux/compiler.h>
#include <asm/synch.h>
#include <asm/asm-compat.h>
#include <linux/bug.h>

/*
 * Atomic exchange
 *
 * Changes the memory location '*p' to be val and returns
 * the previous value stored there.
 */


static __always_inline unsigned long __xchg_u32_local(volatile void *p, unsigned long val) { unsigned long prev; __asm__ __volatile__( "1: lwarx %0,0,%2 \n" PPC405_ERR77(0,%2) " stwcx. %3,0,%2 \n\ bne- 1b" : "=&r" (prev), "+m" (*(volatile unsigned int *)p) : "r" (p), "r" (val) : "cc", "memory"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells2592.59%150.00%
boqun fengboqun feng27.41%150.00%
Total27100.00%2100.00%


static __always_inline unsigned long __xchg_u32_relaxed(u32 *p, unsigned long val) { unsigned long prev; __asm__ __volatile__( "1: lwarx %0,0,%2\n" PPC405_ERR77(0, %2) " stwcx. %3,0,%2\n" " bne- 1b" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (val) : "cc"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells2388.46%150.00%
boqun fengboqun feng311.54%150.00%
Total26100.00%2100.00%

#ifdef CONFIG_PPC64
static __always_inline unsigned long __xchg_u64_local(volatile void *p, unsigned long val) { unsigned long prev; __asm__ __volatile__( "1: ldarx %0,0,%2 \n" PPC405_ERR77(0,%2) " stdcx. %3,0,%2 \n\ bne- 1b" : "=&r" (prev), "+m" (*(volatile unsigned long *)p) : "r" (p), "r" (val) : "cc", "memory"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells2592.59%150.00%
boqun fengboqun feng27.41%150.00%
Total27100.00%2100.00%


static __always_inline unsigned long __xchg_u64_relaxed(u64 *p, unsigned long val) { unsigned long prev; __asm__ __volatile__( "1: ldarx %0,0,%2\n" PPC405_ERR77(0, %2) " stdcx. %3,0,%2\n" " bne- 1b" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (val) : "cc"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells2388.46%150.00%
boqun fengboqun feng311.54%150.00%
Total26100.00%2100.00%

#endif
static __always_inline unsigned long __xchg_local(volatile void *ptr, unsigned long x, unsigned int size) { switch (size) { case 4: return __xchg_u32_local(ptr, x); #ifdef CONFIG_PPC64 case 8: return __xchg_u64_local(ptr, x); #endif } BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg"); return x; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells5585.94%133.33%
pan xinhuipan xinhui69.38%133.33%
boqun fengboqun feng34.69%133.33%
Total64100.00%3100.00%


static __always_inline unsigned long __xchg_relaxed(void *ptr, unsigned long x, unsigned int size) { switch (size) { case 4: return __xchg_u32_relaxed(ptr, x); #ifdef CONFIG_PPC64 case 8: return __xchg_u64_relaxed(ptr, x); #endif } BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_local"); return x; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells5485.71%133.33%
pan xinhuipan xinhui69.52%133.33%
boqun fengboqun feng34.76%133.33%
Total63100.00%3100.00%

#define xchg_local(ptr,x) \ ({ \ __typeof__(*(ptr)) _x_ = (x); \ (__typeof__(*(ptr))) __xchg_local((ptr), \ (unsigned long)_x_, sizeof(*(ptr))); \ }) #define xchg_relaxed(ptr, x) \ ({ \ __typeof__(*(ptr)) _x_ = (x); \ (__typeof__(*(ptr))) __xchg_relaxed((ptr), \ (unsigned long)_x_, sizeof(*(ptr))); \ }) /* * Compare and exchange - if *p == old, set it to new, * and return the old value of *p. */
static __always_inline unsigned long __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new) { unsigned int prev; __asm__ __volatile__ ( PPC_ATOMIC_ENTRY_BARRIER "1: lwarx %0,0,%2 # __cmpxchg_u32\n\ cmpw 0,%0,%3\n\ bne- 2f\n" PPC405_ERR77(0,%2) " stwcx. %4,0,%2\n\ bne- 1b" PPC_ATOMIC_EXIT_BARRIER "\n\ 2:" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (old), "r" (new) : "cc", "memory"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells3196.88%150.00%
boqun fengboqun feng13.12%150.00%
Total32100.00%2100.00%


static __always_inline unsigned long __cmpxchg_u32_local(volatile unsigned int *p, unsigned long old, unsigned long new) { unsigned int prev; __asm__ __volatile__ ( "1: lwarx %0,0,%2 # __cmpxchg_u32\n\ cmpw 0,%0,%3\n\ bne- 2f\n" PPC405_ERR77(0,%2) " stwcx. %4,0,%2\n\ bne- 1b" "\n\ 2:" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (old), "r" (new) : "cc", "memory"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells32100.00%1100.00%
Total32100.00%1100.00%


static __always_inline unsigned long __cmpxchg_u32_relaxed(u32 *p, unsigned long old, unsigned long new) { unsigned long prev; __asm__ __volatile__ ( "1: lwarx %0,0,%2 # __cmpxchg_u32_relaxed\n" " cmpw 0,%0,%3\n" " bne- 2f\n" PPC405_ERR77(0, %2) " stwcx. %4,0,%2\n" " bne- 1b\n" "2:" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (old), "r" (new) : "cc"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
boqun fengboqun feng30100.00%1100.00%
Total30100.00%1100.00%

/* * cmpxchg family don't have order guarantee if cmp part fails, therefore we * can avoid superfluous barriers if we use assembly code to implement * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for * cmpxchg_release() because that will result in putting a barrier in the * middle of a ll/sc loop, which is probably a bad idea. For example, this * might cause the conditional store more likely to fail. */
static __always_inline unsigned long __cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new) { unsigned long prev; __asm__ __volatile__ ( "1: lwarx %0,0,%2 # __cmpxchg_u32_acquire\n" " cmpw 0,%0,%3\n" " bne- 2f\n" PPC405_ERR77(0, %2) " stwcx. %4,0,%2\n" " bne- 1b\n" PPC_ACQUIRE_BARRIER "\n" "2:" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (old), "r" (new) : "cc", "memory"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
boqun fengboqun feng30100.00%1100.00%
Total30100.00%1100.00%

#ifdef CONFIG_PPC64
static __always_inline unsigned long __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new) { unsigned long prev; __asm__ __volatile__ ( PPC_ATOMIC_ENTRY_BARRIER "1: ldarx %0,0,%2 # __cmpxchg_u64\n\ cmpd 0,%0,%3\n\ bne- 2f\n\ stdcx. %4,0,%2\n\ bne- 1b" PPC_ATOMIC_EXIT_BARRIER "\n\ 2:" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (old), "r" (new) : "cc", "memory"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells3196.88%150.00%
boqun fengboqun feng13.12%150.00%
Total32100.00%2100.00%


static __always_inline unsigned long __cmpxchg_u64_local(volatile unsigned long *p, unsigned long old, unsigned long new) { unsigned long prev; __asm__ __volatile__ ( "1: ldarx %0,0,%2 # __cmpxchg_u64\n\ cmpd 0,%0,%3\n\ bne- 2f\n\ stdcx. %4,0,%2\n\ bne- 1b" "\n\ 2:" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (old), "r" (new) : "cc", "memory"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells32100.00%1100.00%
Total32100.00%1100.00%


static __always_inline unsigned long __cmpxchg_u64_relaxed(u64 *p, unsigned long old, unsigned long new) { unsigned long prev; __asm__ __volatile__ ( "1: ldarx %0,0,%2 # __cmpxchg_u64_relaxed\n" " cmpd 0,%0,%3\n" " bne- 2f\n" " stdcx. %4,0,%2\n" " bne- 1b\n" "2:" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (old), "r" (new) : "cc"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
boqun fengboqun feng30100.00%1100.00%
Total30100.00%1100.00%


static __always_inline unsigned long __cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new) { unsigned long prev; __asm__ __volatile__ ( "1: ldarx %0,0,%2 # __cmpxchg_u64_acquire\n" " cmpd 0,%0,%3\n" " bne- 2f\n" " stdcx. %4,0,%2\n" " bne- 1b\n" PPC_ACQUIRE_BARRIER "\n" "2:" : "=&r" (prev), "+m" (*p) : "r" (p), "r" (old), "r" (new) : "cc", "memory"); return prev; }

Contributors

PersonTokensPropCommitsCommitProp
boqun fengboqun feng30100.00%1100.00%
Total30100.00%1100.00%

#endif
static __always_inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, unsigned int size) { switch (size) { case 4: return __cmpxchg_u32(ptr, old, new); #ifdef CONFIG_PPC64 case 8: return __cmpxchg_u64(ptr, old, new); #endif } BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg"); return old; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells6691.67%150.00%
pan xinhuipan xinhui68.33%150.00%
Total72100.00%2100.00%


static __always_inline unsigned long __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, unsigned int size) { switch (size) { case 4: return __cmpxchg_u32_local(ptr, old, new); #ifdef CONFIG_PPC64 case 8: return __cmpxchg_u64_local(ptr, old, new); #endif } BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_local"); return old; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells6691.67%150.00%
pan xinhuipan xinhui68.33%150.00%
Total72100.00%2100.00%


static __always_inline unsigned long __cmpxchg_relaxed(void *ptr, unsigned long old, unsigned long new, unsigned int size) { switch (size) { case 4: return __cmpxchg_u32_relaxed(ptr, old, new); #ifdef CONFIG_PPC64 case 8: return __cmpxchg_u64_relaxed(ptr, old, new); #endif } BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_relaxed"); return old; }

Contributors

PersonTokensPropCommitsCommitProp
boqun fengboqun feng6591.55%150.00%
pan xinhuipan xinhui68.45%150.00%
Total71100.00%2100.00%


static __always_inline unsigned long __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new, unsigned int size) { switch (size) { case 4: return __cmpxchg_u32_acquire(ptr, old, new); #ifdef CONFIG_PPC64 case 8: return __cmpxchg_u64_acquire(ptr, old, new); #endif } BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_acquire"); return old; }

Contributors

PersonTokensPropCommitsCommitProp
boqun fengboqun feng6591.55%150.00%
pan xinhuipan xinhui68.45%150.00%
Total71100.00%2100.00%

#define cmpxchg(ptr, o, n) \ ({ \ __typeof__(*(ptr)) _o_ = (o); \ __typeof__(*(ptr)) _n_ = (n); \ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ (unsigned long)_n_, sizeof(*(ptr))); \ }) #define cmpxchg_local(ptr, o, n) \ ({ \ __typeof__(*(ptr)) _o_ = (o); \ __typeof__(*(ptr)) _n_ = (n); \ (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ (unsigned long)_n_, sizeof(*(ptr))); \ }) #define cmpxchg_relaxed(ptr, o, n) \ ({ \ __typeof__(*(ptr)) _o_ = (o); \ __typeof__(*(ptr)) _n_ = (n); \ (__typeof__(*(ptr))) __cmpxchg_relaxed((ptr), \ (unsigned long)_o_, (unsigned long)_n_, \ sizeof(*(ptr))); \ }) #define cmpxchg_acquire(ptr, o, n) \ ({ \ __typeof__(*(ptr)) _o_ = (o); \ __typeof__(*(ptr)) _n_ = (n); \ (__typeof__(*(ptr))) __cmpxchg_acquire((ptr), \ (unsigned long)_o_, (unsigned long)_n_, \ sizeof(*(ptr))); \ }) #ifdef CONFIG_PPC64 #define cmpxchg64(ptr, o, n) \ ({ \ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ cmpxchg((ptr), (o), (n)); \ }) #define cmpxchg64_local(ptr, o, n) \ ({ \ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ cmpxchg_local((ptr), (o), (n)); \ }) #define cmpxchg64_relaxed(ptr, o, n) \ ({ \ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ cmpxchg_relaxed((ptr), (o), (n)); \ }) #define cmpxchg64_acquire(ptr, o, n) \ ({ \ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ cmpxchg_acquire((ptr), (o), (n)); \ }) #else #include <asm-generic/cmpxchg-local.h> #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) #endif #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_CMPXCHG_H_ */

Overall Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells58361.76%116.67%
boqun fengboqun feng31933.79%350.00%
pan xinhuipan xinhui394.13%116.67%
michael ellermanmichael ellerman30.32%116.67%
Total944100.00%6100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.