Subject: Generic this_cpu based operations Provide generic functions that are used if an arch does not define optimized this_cpu operations. The functions come in two flavors: One for contexts in which we do now that preemption is off or we do not care and another that switches off preemption. Signed-off-by: Christoph Lameter --- include/linux/percpu.h | 103 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) Index: linux-2.6/include/linux/percpu.h =================================================================== --- linux-2.6.orig/include/linux/percpu.h 2009-05-28 16:03:17.000000000 -0500 +++ linux-2.6/include/linux/percpu.h 2009-05-28 16:30:40.000000000 -0500 @@ -187,4 +187,107 @@ do { \ # define percpu_xor(var, val) __percpu_generic_to_op(var, (val), ^=) #endif + +/* + * Optimized manipulation for memory allocated through the per cpu + * allocator or for addresses taken from per cpu variables. + * + * The first group is used for accesses that must be done in a + * preemption safe way since we know that the context is not preempt + * safe + */ +#ifndef this_cpu_read +# define this_cpu_read(pcp) \ + ({ \ + *this_cpu_ptr(pcp); \ + }) +#endif + +#define _this_cpu_generic_to_op(pcp, val, op) \ +do { \ + *this_cpu_ptr((pcp) op val; \ +} while (0) + +#ifndef this_cpu_write +# define this_cpu_write(pcp, val) __this_cpu_write((pcp), (val)) +#endif + +#ifndef this_cpu_add +# define this_cpu_add(pcp, val) _this_cpu_generic_to_op((pcp), (val), +=) +#endif + +#ifndef this_cpu_sub +# define this_cpu_sub(pcp, val) _this_cpu_generic_add((pcp), -(var)) +#endif + +#ifndef this_cpu_inc +# define this_cpu_inc(pcp) this_cpu_add((pcp), 1) +#endif + +#ifndef this_cpu_dec +# define this_cpu_dec(pcp) this_cpu_sub((pcp), 1) +#endif + +#ifndef this_cpu_and +# define this_cpu_and(pcp, val) _this_cpu_generic_to_op((pcp), (val), &=) +#endif + +#ifndef this_cpu_or +# define this_cpu_or(pcp, val) _this_cpu_generic_to_op((pcp), (val), |=) +#endif + +#ifndef this_cpu_xor +# define this_cpu_xor(pcp, val) _this_cpu_generic_to_op((pcp), (val), ^=) +#endif + + +/* + * Generic percpu operations that do not require preemption handling. + * Either we do not care about races or the caller has the + * responsibility of handling preemptions issues. + */ +#ifndef __this_cpu_read +# define __this_cpu_read(pcp) \ + ({ \ + *__this_cpu_ptr(pcp); \ + }) +#endif + +#define __this_cpu_generic_to_op(pcp, val, op) \ +do { \ + *__this_cpu_ptr((pcp) op val; \ +} while (0) + +#ifndef __this_cpu_write +# define __this_cpu_write(pcp, val) __this_cpu_generic_to_op((pcp), (val), =) +#endif + +#ifndef __this_cpu_add +# define __this_cpu_add(pcp, val) __this_cpu_generic_to_op((pcp), (val), +=) +#endif + +#ifndef __this_cpu_sub +# define __this_cpu_sub(pcp, val) __this_cpu_generic_add((pcp), -(var)) +#endif + +#ifndef __this_cpu_inc +# define __this_cpu_inc(pcp) __this_cpu_add((pcp), 1) +#endif + +#ifndef __this_cpu_dec +# define __this_cpu_dec(pcp) __this_cpu_sub((pcp), 1) +#endif + +#ifndef __this_cpu_and +# define __this_cpu_and(pcp, val) __this_cpu_generic_to_op((pcp), (val), &=) +#endif + +#ifndef __this_cpu_or +# define __this_cpu_or(pcp, val) __this_cpu_generic_to_op((pcp), (val), |=) +#endif + +#ifndef __this_cpu_xor +# define __this_cpu_xor(pcp, val) __this_cpu_generic_to_op((pcp), (val), ^=) +#endif + #endif /* __LINUX_PERCPU_H */