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

x86/percpu: Rewrite x86_this_cpu_test_bit() and friends as macros

Rewrite the whole family of x86_this_cpu_test_bit() functions
as macros, so standard __my_cpu_var() and raw_cpu_read() macros
can be used on percpu variables. This approach considerably
simplifies implementation of functions and also introduces
standard checks on accessed percpu variables.

No functional changes intended.

Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/20240404094218.448963-2-ubizjak@gmail.com

authored by

Uros Bizjak and committed by
Ingo Molnar
a3f8a3a2 4c3677c0

+24 -34
+1 -2
arch/um/include/asm/cpufeature.h
··· 38 38 39 39 #define this_cpu_has(bit) \ 40 40 (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ 41 - x86_this_cpu_test_bit(bit, \ 42 - (unsigned long __percpu *)&cpu_info.x86_capability)) 41 + x86_this_cpu_test_bit(bit, cpu_info.x86_capability)) 43 42 44 43 /* 45 44 * This macro is for detection of features which need kernel
+1 -2
arch/x86/include/asm/cpufeature.h
··· 127 127 128 128 #define this_cpu_has(bit) \ 129 129 (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ 130 - x86_this_cpu_test_bit(bit, \ 131 - (unsigned long __percpu *)&cpu_info.x86_capability)) 130 + x86_this_cpu_test_bit(bit, cpu_info.x86_capability)) 132 131 133 132 /* 134 133 * This macro is for detection of features which need kernel
+22 -30
arch/x86/include/asm/percpu.h
··· 96 96 #endif /* CONFIG_SMP */ 97 97 98 98 #define __my_cpu_type(var) typeof(var) __percpu_seg_override 99 - #define __my_cpu_ptr(ptr) (__my_cpu_type(*ptr)*)(__force uintptr_t)(ptr) 99 + #define __my_cpu_ptr(ptr) (__my_cpu_type(*(ptr))*)(__force uintptr_t)(ptr) 100 100 #define __my_cpu_var(var) (*__my_cpu_ptr(&(var))) 101 101 #define __percpu_arg(x) __percpu_prefix "%" #x 102 102 #define __force_percpu_arg(x) __force_percpu_prefix "%" #x ··· 568 568 #define this_cpu_read_stable_8(pcp) ({ BUILD_BUG(); (typeof(pcp))0; }) 569 569 #endif 570 570 571 - static __always_inline bool x86_this_cpu_constant_test_bit(unsigned int nr, 572 - const unsigned long __percpu *addr) 573 - { 574 - unsigned long __percpu *a = 575 - (unsigned long __percpu *)addr + nr / BITS_PER_LONG; 571 + #define x86_this_cpu_constant_test_bit(_nr, _var) \ 572 + ({ \ 573 + unsigned long __percpu *addr__ = \ 574 + (unsigned long __percpu *)&(_var) + ((_nr) / BITS_PER_LONG); \ 575 + !!((1UL << ((_nr) % BITS_PER_LONG)) & raw_cpu_read(*addr__)); \ 576 + }) 576 577 577 - #ifdef CONFIG_X86_64 578 - return ((1UL << (nr % BITS_PER_LONG)) & raw_cpu_read_8(*a)) != 0; 579 - #else 580 - return ((1UL << (nr % BITS_PER_LONG)) & raw_cpu_read_4(*a)) != 0; 581 - #endif 582 - } 578 + #define x86_this_cpu_variable_test_bit(_nr, _var) \ 579 + ({ \ 580 + bool oldbit; \ 581 + \ 582 + asm volatile("btl %[nr], " __percpu_arg([var]) \ 583 + CC_SET(c) \ 584 + : CC_OUT(c) (oldbit) \ 585 + : [var] "m" (__my_cpu_var(_var)), \ 586 + [nr] "rI" (_nr)); \ 587 + oldbit; \ 588 + }) 583 589 584 - static inline bool x86_this_cpu_variable_test_bit(int nr, 585 - const unsigned long __percpu *addr) 586 - { 587 - bool oldbit; 588 - 589 - asm volatile("btl %[nr], " __percpu_arg([var]) 590 - CC_SET(c) 591 - : CC_OUT(c) (oldbit) 592 - : [var] "m" (*__my_cpu_ptr((unsigned long __percpu *)(addr))), 593 - [nr] "Ir" (nr)); 594 - 595 - return oldbit; 596 - } 597 - 598 - #define x86_this_cpu_test_bit(nr, addr) \ 599 - (__builtin_constant_p((nr)) \ 600 - ? x86_this_cpu_constant_test_bit((nr), (addr)) \ 601 - : x86_this_cpu_variable_test_bit((nr), (addr))) 590 + #define x86_this_cpu_test_bit(_nr, _var) \ 591 + (__builtin_constant_p(_nr) \ 592 + ? x86_this_cpu_constant_test_bit(_nr, _var) \ 593 + : x86_this_cpu_variable_test_bit(_nr, _var)) 602 594 603 595 604 596 #include <asm-generic/percpu.h>