--- arch/x86/include/asm/percpu.h | 66 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) Index: linux-2.6/arch/x86/include/asm/percpu.h =================================================================== --- linux-2.6.orig/arch/x86/include/asm/percpu.h 2009-09-16 16:21:14.000000000 -0500 +++ linux-2.6/arch/x86/include/asm/percpu.h 2009-09-16 17:59:32.000000000 -0500 @@ -153,8 +153,70 @@ do { \ #define percpu_or(var, val) percpu_to_op("or", per_cpu__##var, val) #define percpu_xor(var, val) percpu_to_op("xor", per_cpu__##var, val) -#define __this_cpu_read(pcp) percpu_from_op("mov", pcp) -#define __this_cpu_write(pcp, val) percpu_to_op("mov", (pcp), val) +#define __percpu_to_op(op, var, val) \ +do { \ + typedef typeof(var) T__; \ + if (0) { \ + T__ tmp__; \ + tmp__ = (val); \ + } \ + asm(op " %1,"__percpu_arg(0) \ + : "+m" (var) \ + : "ri" ((T__)(val))); \ +} while (0) + +#define __percpu_from_op(op, var, constraint) \ +({ \ + typeof(var) ret__; \ + asm(op " " __percpu_arg(1) ",%0" \ + : "=r" (ret__) \ + : constraint); \ + ret__; \ +}) + +#define __this_cpu_read_1(pcp) __percpu_from_op("movb", (pcp), "m" (pcp)) +#define __this_cpu_read_2(pcp) __percpu_from_op("movw", (pcp), "m" (pcp)) +#define __this_cpu_read_4(pcp) __percpu_from_op("movl", (pcp), "m" (pcp)) +#define __this_cpu_read_8(pcp) __percpu_from_op("movq", (pcp), "m" (pcp)) +// #define __this_cpu_read_q(pcp) (*__this_cpu_ptr(&(pcp))) + +#define __this_cpu_write_1(pcp, val) __percpu_to_op("movb", (pcp), val) +#define __this_cpu_write_2(pcp, val) __percpu_to_op("movw", (pcp), val) +#define __this_cpu_write_4(pcp, val) __percpu_to_op("movl", (pcp), val) +#define __this_cpu_write_8(pcp, val) __percpu_to_op("movq", (pcp), val) + +#define __this_branch_read(identifier, a) \ +({ \ + typeof(a) ret__; \ + switch(sizeof(a)) { \ + case 1: ret__ = identifier##1(a);break; \ + case 2: ret__ = identifier##2(a);break; \ + case 4: ret__ = identifier##4(a);break; \ + case 8: ret__ = identifier##8(a);break; \ + default: \ + __bad_percpu_size(); \ + ret__ = 0; \ + }; \ + ret__; \ +}) + +#define __this_branch_modify(identifier, a, value) \ +do { \ + switch(sizeof(a)) { \ + case 1: identifier##1(a, value);break; \ + case 2: identifier##2(a, value);break; \ + case 4: identifier##4(a, value);break; \ + case 8: identifier##8(a, value);break; \ + default: \ + __bad_percpu_size(); \ + } \ +} while (0) + +#define __this_cpu_read(pcp) __this_branch_read(__this_cpu_read_, (pcp)) +#define __this_cpu_write(pcp, val) __this_branch_modify(__this_cpu_write_, (pcp), (val)) + +// #define __this_cpu_read(pcp) percpu_from_op("mov", pcp) +// #define __this_cpu_write(pcp, val) percpu_to_op("mov", (pcp), val) #define __this_cpu_add(pcp, val) percpu_to_op("add", (pcp), val) #define __this_cpu_sub(pcp, val) percpu_to_op("sub", (pcp), val) #define __this_cpu_and(pcp, val) percpu_to_op("and", (pcp), val)