Re: atomic: add cmpxchg_local to ppc

Mathieu Desnoyers <[email protected]> Tue, 24 Jul 2007 09:41:38 -0400
Newsgroups gmane.linux.kernel.tracing
Message-ID <20070724134138.GA26634@Krystal>
Hi Gunnar,

Thanks for this patch, I just integrated it to my patch set.

I already did some work regarding ppc cmpxchg, could you test it for me?
I will send the patches in the following emails.

Mathieu

* Gunnar Larisch ([email protected]) wrote:
> Hello Mathieu,
> 
> attached is a patch which adds support for cmpxchg_local on "old" ppc.
> I tested the great LTTng (V0.9.10) on an ocotea board, which is only
> supported in ppc architecture.
> 
> Best Regards,
> Gunnar Larisch
> -- 
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: [email protected]
> 
> 
> 
> 

> atomic: add cmpxchg_local to ppc
> 
> Add a local processor version of cmpxchg for ppc
> 
> Signed-off-by: Gunnar Larisch <[email protected]>
> ---
> 
>  include/asm-ppc/system.h |   48 +++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 47 insertions(+), 1 deletions(-)
> 
> diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
> index d84a3cf..16c4331 100644
> --- a/include/asm-ppc/system.h
> +++ b/include/asm-ppc/system.h
> @@ -217,12 +217,34 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
>  	return prev;
>  }
>  
> +static __inline__ unsigned long
> +__cmpxchg_u32_local(volatile unsigned int *p, unsigned int old,
> +	unsigned int new)
> +{
> +	unsigned int prev;
> +
> +	__asm__ __volatile__ ("\n\
> +1:	lwarx	%0,0,%2 \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), "m" (*p)
> +	: "cc", "memory");
> +
> +	return prev;
> +}
> +
>  /* This function doesn't exist, so you'll get a linker error
>     if something tries to do an invalid cmpxchg().  */
>  extern void __cmpxchg_called_with_bad_pointer(void);
>  
>  static __inline__ unsigned long
> -__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
> +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
> +	  unsigned int size)
>  {
>  	switch (size) {
>  	case 4:
> @@ -236,6 +258,22 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
>  	return old;
>  }
>  
> +static __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);
> +#if 0	/* we don't have __cmpxchg_u64_local on 32-bit PPC */
> +	case 8:
> +		return __cmpxchg_u64_local(ptr, old, new);
> +#endif
> +	}
> +	__cmpxchg_called_with_bad_pointer();
> +	return old;
> +}
> +
>  #define cmpxchg(ptr,o,n)						 \
>    ({									 \
>       __typeof__(*(ptr)) _o_ = (o);					 \
> @@ -244,6 +282,14 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
>  				    (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 arch_align_stack(x) (x)
>  
>  #endif /* __KERNEL__ */
> 


-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68