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

Configure Feed

Select the types of activity you want to include in your feed.

bitops: Add non-atomic bitops for pointers

cpumap needs to set, clear, and test the lowest bit in skb pointer in
various places. To make these checks less noisy, add pointer friendly
bitop macros that also do some typechecking to sanitize the argument.

These wrap the non-atomic bitops __set_bit, __clear_bit, and test_bit
but for pointer arguments. Pointer's address has to be passed in and it
is treated as an unsigned long *, since width and representation of
pointer and unsigned long match on targets Linux supports. They are
prefixed with double underscore to indicate lack of atomicity.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/bpf/20210702111825.491065-3-memxor@gmail.com

authored by

Kumar Kartikeya Dwivedi and committed by
Alexei Starovoitov
cb0f8003 fe21cb91

+59
+50
include/linux/bitops.h
··· 4 4 5 5 #include <asm/types.h> 6 6 #include <linux/bits.h> 7 + #include <linux/typecheck.h> 7 8 8 9 #include <uapi/linux/kernel.h> 9 10 ··· 253 252 else 254 253 __clear_bit(nr, addr); 255 254 } 255 + 256 + /** 257 + * __ptr_set_bit - Set bit in a pointer's value 258 + * @nr: the bit to set 259 + * @addr: the address of the pointer variable 260 + * 261 + * Example: 262 + * void *p = foo(); 263 + * __ptr_set_bit(bit, &p); 264 + */ 265 + #define __ptr_set_bit(nr, addr) \ 266 + ({ \ 267 + typecheck_pointer(*(addr)); \ 268 + __set_bit(nr, (unsigned long *)(addr)); \ 269 + }) 270 + 271 + /** 272 + * __ptr_clear_bit - Clear bit in a pointer's value 273 + * @nr: the bit to clear 274 + * @addr: the address of the pointer variable 275 + * 276 + * Example: 277 + * void *p = foo(); 278 + * __ptr_clear_bit(bit, &p); 279 + */ 280 + #define __ptr_clear_bit(nr, addr) \ 281 + ({ \ 282 + typecheck_pointer(*(addr)); \ 283 + __clear_bit(nr, (unsigned long *)(addr)); \ 284 + }) 285 + 286 + /** 287 + * __ptr_test_bit - Test bit in a pointer's value 288 + * @nr: the bit to test 289 + * @addr: the address of the pointer variable 290 + * 291 + * Example: 292 + * void *p = foo(); 293 + * if (__ptr_test_bit(bit, &p)) { 294 + * ... 295 + * } else { 296 + * ... 297 + * } 298 + */ 299 + #define __ptr_test_bit(nr, addr) \ 300 + ({ \ 301 + typecheck_pointer(*(addr)); \ 302 + test_bit(nr, (unsigned long *)(addr)); \ 303 + }) 256 304 257 305 #ifdef __KERNEL__ 258 306
+9
include/linux/typecheck.h
··· 22 22 (void)__tmp; \ 23 23 }) 24 24 25 + /* 26 + * Check at compile time that something is a pointer type. 27 + */ 28 + #define typecheck_pointer(x) \ 29 + ({ typeof(x) __dummy; \ 30 + (void)sizeof(*__dummy); \ 31 + 1; \ 32 + }) 33 + 25 34 #endif /* TYPECHECK_H_INCLUDED */