Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/percpu: Clean up percpu_stable_op()

Use __pcpu_size_call_return() to simplify this_cpu_read_stable().
Also remove __bad_percpu_size() which is now unused.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Dennis Zhou <dennis@kernel.org>
Link: https://lkml.kernel.org/r/20200720204925.3654302-10-ndesaulniers@google.com

authored by

Brian Gerst and committed by
Thomas Gleixner
c94055fe ebcd580b

+12 -29
+12 -29
arch/x86/include/asm/percpu.h
··· 85 85 86 86 /* For arch-specific code, we can use direct single-insn ops (they 87 87 * don't give an lvalue though). */ 88 - extern void __bad_percpu_size(void); 89 88 90 89 #define __pcpu_type_1 u8 91 90 #define __pcpu_type_2 u16 ··· 166 167 (typeof(_var))(unsigned long) pfo_val__; \ 167 168 }) 168 169 169 - #define percpu_stable_op(op, var) \ 170 - ({ \ 171 - typeof(var) pfo_ret__; \ 172 - switch (sizeof(var)) { \ 173 - case 1: \ 174 - asm(op "b "__percpu_arg(P1)",%0" \ 175 - : "=q" (pfo_ret__) \ 176 - : "p" (&(var))); \ 177 - break; \ 178 - case 2: \ 179 - asm(op "w "__percpu_arg(P1)",%0" \ 180 - : "=r" (pfo_ret__) \ 181 - : "p" (&(var))); \ 182 - break; \ 183 - case 4: \ 184 - asm(op "l "__percpu_arg(P1)",%0" \ 185 - : "=r" (pfo_ret__) \ 186 - : "p" (&(var))); \ 187 - break; \ 188 - case 8: \ 189 - asm(op "q "__percpu_arg(P1)",%0" \ 190 - : "=r" (pfo_ret__) \ 191 - : "p" (&(var))); \ 192 - break; \ 193 - default: __bad_percpu_size(); \ 194 - } \ 195 - pfo_ret__; \ 170 + #define percpu_stable_op(size, op, _var) \ 171 + ({ \ 172 + __pcpu_type_##size pfo_val__; \ 173 + asm(__pcpu_op2_##size(op, __percpu_arg(P[var]), "%[val]") \ 174 + : [val] __pcpu_reg_##size("=", pfo_val__) \ 175 + : [var] "p" (&(_var))); \ 176 + (typeof(_var))(unsigned long) pfo_val__; \ 196 177 }) 197 178 198 179 /* ··· 237 258 * per-thread variables implemented as per-cpu variables and thus 238 259 * stable for the duration of the respective task. 239 260 */ 240 - #define this_cpu_read_stable(var) percpu_stable_op("mov", var) 261 + #define this_cpu_read_stable_1(pcp) percpu_stable_op(1, "mov", pcp) 262 + #define this_cpu_read_stable_2(pcp) percpu_stable_op(2, "mov", pcp) 263 + #define this_cpu_read_stable_4(pcp) percpu_stable_op(4, "mov", pcp) 264 + #define this_cpu_read_stable_8(pcp) percpu_stable_op(8, "mov", pcp) 265 + #define this_cpu_read_stable(pcp) __pcpu_size_call_return(this_cpu_read_stable_, pcp) 241 266 242 267 #define raw_cpu_read_1(pcp) percpu_from_op(1, , "mov", pcp) 243 268 #define raw_cpu_read_2(pcp) percpu_from_op(2, , "mov", pcp)