Message ID | 20220624121313.2382500-3-alexandr.lobakin@intel.com |
---|---|
State | New |
Headers | show |
Series | bitops: let optimize out non-atomic bitops on compile-time constants | expand |
On Fri, Jun 24, 2022 at 02:13:06PM +0200, Alexander Lobakin wrote: > Move generic non-atomic bitops from the asm-generic header which > gets included only when there are no architecture-specific > alternatives, to a separate independent file to make them always > available. > Almost no actual code changes, only one comment added to > generic_test_bit() saying that it's an atomic operation itself > and thus `volatile` must always stay there with no cast-aways. > > Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> # comment > Suggested-by: Marco Elver <elver@google.com> # reference to kernel-doc > Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com> > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > Reviewed-by: Marco Elver <elver@google.com> > --- > .../asm-generic/bitops/generic-non-atomic.h | 130 ++++++++++++++++++ > include/asm-generic/bitops/non-atomic.h | 110 ++------------- > 2 files changed, 138 insertions(+), 102 deletions(-) > create mode 100644 include/asm-generic/bitops/generic-non-atomic.h > Hi, this patch gives me a headache when trying to run sparse against a module. Olek please help :D $ sudo make C=2 -C . M=drivers/net/ethernet/intel/ice/ make: Entering directory '/home/mfijalko/bpf-next' CHECK drivers/net/ethernet/intel/ice/ice_main.c drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./arch/x86/include/asm/bitops.h:66:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/generic-non-atomic.h:30:9: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:31:9: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:33:10: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:33:16: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:28:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through arch/x86/include/asm/bitops.h, include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/instrumented-non-atomic.h:26:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./arch/x86/include/asm/bitops.h:92:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/generic-non-atomic.h:39:9: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:40:9: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:42:10: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:42:16: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:37:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through arch/x86/include/asm/bitops.h, include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/instrumented-non-atomic.h:42:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./arch/x86/include/asm/bitops.h:117:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/generic-non-atomic.h:57:9: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:58:9: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:60:10: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:60:15: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:55:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through arch/x86/include/asm/bitops.h, include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/instrumented-non-atomic.h:58:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./arch/x86/include/asm/bitops.h:150:9: warning: unreplaced symbol 'oldbit' ./arch/x86/include/asm/bitops.h:154:26: warning: unreplaced symbol 'oldbit' ./arch/x86/include/asm/bitops.h:156:16: warning: unreplaced symbol 'oldbit' ./arch/x86/include/asm/bitops.h:156:9: warning: unreplaced symbol 'return' ./arch/x86/include/asm/bitops.h:148:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/generic-non-atomic.h:75:9: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:76:9: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:77:9: warning: unreplaced symbol 'old' ./include/asm-generic/bitops/generic-non-atomic.h:79:10: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:79:14: warning: unreplaced symbol 'old' ./include/asm-generic/bitops/generic-non-atomic.h:79:20: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:80:17: warning: unreplaced symbol 'old' ./include/asm-generic/bitops/generic-non-atomic.h:80:23: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:80:9: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/generic-non-atomic.h:73:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through arch/x86/include/asm/bitops.h, include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/instrumented-non-atomic.h:100:9: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/instrumented-non-atomic.h:97:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/generic-non-atomic.h:95:9: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:96:9: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:97:9: warning: unreplaced symbol 'old' ./include/asm-generic/bitops/generic-non-atomic.h:99:10: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:99:14: warning: unreplaced symbol 'old' ./include/asm-generic/bitops/generic-non-atomic.h:99:21: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:100:17: warning: unreplaced symbol 'old' ./include/asm-generic/bitops/generic-non-atomic.h:100:23: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:100:9: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/generic-non-atomic.h:93:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through arch/x86/include/asm/bitops.h, include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/instrumented-non-atomic.h:115:9: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/instrumented-non-atomic.h:112:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./arch/x86/include/asm/bitops.h:188:9: warning: unreplaced symbol 'oldbit' ./arch/x86/include/asm/bitops.h:192:35: warning: unreplaced symbol 'oldbit' ./arch/x86/include/asm/bitops.h:195:16: warning: unreplaced symbol 'oldbit' ./arch/x86/include/asm/bitops.h:195:9: warning: unreplaced symbol 'return' ./arch/x86/include/asm/bitops.h:186:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/generic-non-atomic.h:107:9: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:108:9: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:109:9: warning: unreplaced symbol 'old' ./include/asm-generic/bitops/generic-non-atomic.h:111:10: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:111:14: warning: unreplaced symbol 'old' ./include/asm-generic/bitops/generic-non-atomic.h:111:20: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:112:17: warning: unreplaced symbol 'old' ./include/asm-generic/bitops/generic-non-atomic.h:112:23: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:112:9: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/generic-non-atomic.h:105:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through arch/x86/include/asm/bitops.h, include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/instrumented-non-atomic.h:130:9: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/instrumented-non-atomic.h:127:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./arch/x86/include/asm/bitops.h:239:9: warning: unreplaced symbol 'return' ./arch/x86/include/asm/bitops.h:237:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/generic-non-atomic.h:128:9: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/generic-non-atomic.h:121:1: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/generic-non-atomic.h:168:9: warning: unreplaced symbol 'p' ./include/asm-generic/bitops/generic-non-atomic.h:169:9: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:170:9: warning: unreplaced symbol 'val' ./include/asm-generic/bitops/generic-non-atomic.h:172:19: warning: unreplaced symbol 'val' ./include/asm-generic/bitops/generic-non-atomic.h:172:25: warning: unreplaced symbol 'mask' ./include/asm-generic/bitops/generic-non-atomic.h:172:9: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/generic-non-atomic.h:166:1: warning: unreplaced symbol 'return' drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through arch/x86/include/asm/bitops.h, include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): ./include/asm-generic/bitops/instrumented-non-atomic.h:142:9: warning: unreplaced symbol 'return' ./include/asm-generic/bitops/instrumented-non-atomic.h:139:1: warning: unreplaced symbol 'return' that's for a single file, there's no point in including same output for every other file being checked. Thanks, Maciej
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Date: Mon, 2 Jan 2023 17:14:31 +0100 > On Fri, Jun 24, 2022 at 02:13:06PM +0200, Alexander Lobakin wrote: > > Move generic non-atomic bitops from the asm-generic header which > > gets included only when there are no architecture-specific > > alternatives, to a separate independent file to make them always > > available. > > Almost no actual code changes, only one comment added to > > generic_test_bit() saying that it's an atomic operation itself > > and thus `volatile` must always stay there with no cast-aways. > > > > Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> # comment > > Suggested-by: Marco Elver <elver@google.com> # reference to kernel-doc > > Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com> > > Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > > Reviewed-by: Marco Elver <elver@google.com> > > --- > > .../asm-generic/bitops/generic-non-atomic.h | 130 ++++++++++++++++++ > > include/asm-generic/bitops/non-atomic.h | 110 ++------------- > > 2 files changed, 138 insertions(+), 102 deletions(-) > > create mode 100644 include/asm-generic/bitops/generic-non-atomic.h > > > > Hi, > > this patch gives me a headache when trying to run sparse against a module. > > Olek please help :D It was fixed shortly after the build bots turned on on the original series with [0]. Hovewer, no release tag's been made after the fix. There's also a short discussion regarding packaging Sparse 0.6.4 for Debian with that fix cherry-picked[1], not sure if it led anywhere. > > $ sudo make C=2 -C . M=drivers/net/ethernet/intel/ice/ > make: Entering directory '/home/mfijalko/bpf-next' > CHECK drivers/net/ethernet/intel/ice/ice_main.c > drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): > ./arch/x86/include/asm/bitops.h:66:1: warning: unreplaced symbol 'return' [...] > drivers/net/ethernet/intel/ice/ice_main.c: note: in included file (through arch/x86/include/asm/bitops.h, include/linux/bitops.h, include/linux/kernel.h, drivers/net/ethernet/intel/ice/ice.h): > ./include/asm-generic/bitops/instrumented-non-atomic.h:142:9: warning: unreplaced symbol 'return' > ./include/asm-generic/bitops/instrumented-non-atomic.h:139:1: warning: unreplaced symbol 'return' > > that's for a single file, there's no point in including same output for > every other file being checked. > > Thanks, > Maciej [0] https://git.kernel.org/pub/scm/devel/sparse/sparse.git/commit/?id=0e1aae55e49cad7ea43848af5b58ff0f57e7af99 [1] https://lore.kernel.org/all/Yr7kPM1wLZnOqxOA@smile.fi.intel.com Thanks, Olek
On Mon, Jan 02, 2023 at 05:30:59PM +0100, Alexander Lobakin wrote: > From: Maciej Fijalkowski <maciej.fijalkowski@intel.com> > Date: Mon, 2 Jan 2023 17:14:31 +0100 > > On Fri, Jun 24, 2022 at 02:13:06PM +0200, Alexander Lobakin wrote: > > this patch gives me a headache when trying to run sparse against a module. No, it's not related to this patch. > > Olek please help :D > > It was fixed shortly after the build bots turned on on the original > series with [0]. Hovewer, no release tag's been made after the fix. > There's also a short discussion regarding packaging Sparse 0.6.4 for > Debian with that fix cherry-picked[1], not sure if it led anywhere. Debian already fixed that for a few weeks at least.
diff --git a/include/asm-generic/bitops/generic-non-atomic.h b/include/asm-generic/bitops/generic-non-atomic.h new file mode 100644 index 000000000000..7226488810e5 --- /dev/null +++ b/include/asm-generic/bitops/generic-non-atomic.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ASM_GENERIC_BITOPS_GENERIC_NON_ATOMIC_H +#define __ASM_GENERIC_BITOPS_GENERIC_NON_ATOMIC_H + +#include <linux/bits.h> + +#ifndef _LINUX_BITOPS_H +#error only <linux/bitops.h> can be included directly +#endif + +/* + * Generic definitions for bit operations, should not be used in regular code + * directly. + */ + +/** + * generic___set_bit - Set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike set_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __always_inline void +generic___set_bit(unsigned int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + *p |= mask; +} + +static __always_inline void +generic___clear_bit(unsigned int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + *p &= ~mask; +} + +/** + * generic___change_bit - Toggle a bit in memory + * @nr: the bit to change + * @addr: the address to start counting from + * + * Unlike change_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __always_inline +void generic___change_bit(unsigned int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + *p ^= mask; +} + +/** + * generic___test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __always_inline int +generic___test_and_set_bit(unsigned int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old = *p; + + *p = old | mask; + return (old & mask) != 0; +} + +/** + * generic___test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to clear + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __always_inline int +generic___test_and_clear_bit(unsigned int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old = *p; + + *p = old & ~mask; + return (old & mask) != 0; +} + +/* WARNING: non atomic and it can be reordered! */ +static __always_inline int +generic___test_and_change_bit(unsigned int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old = *p; + + *p = old ^ mask; + return (old & mask) != 0; +} + +/** + * generic_test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static __always_inline int +generic_test_bit(unsigned int nr, const volatile unsigned long *addr) +{ + /* + * Unlike the bitops with the '__' prefix above, this one *is* atomic, + * so `volatile` must always stay here with no cast-aways. See + * `Documentation/atomic_bitops.txt` for the details. + */ + return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); +} + +#endif /* __ASM_GENERIC_BITOPS_GENERIC_NON_ATOMIC_H */ diff --git a/include/asm-generic/bitops/non-atomic.h b/include/asm-generic/bitops/non-atomic.h index 078cc68be2f1..23d3abc1e10d 100644 --- a/include/asm-generic/bitops/non-atomic.h +++ b/include/asm-generic/bitops/non-atomic.h @@ -2,121 +2,27 @@ #ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ #define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ -#include <asm/types.h> +#include <asm-generic/bitops/generic-non-atomic.h> -/** - * arch___set_bit - Set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * Unlike set_bit(), this function is non-atomic and may be reordered. - * If it's called on the same region of memory simultaneously, the effect - * may be that only one operation succeeds. - */ -static __always_inline void -arch___set_bit(unsigned int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - - *p |= mask; -} +#define arch___set_bit generic___set_bit #define __set_bit arch___set_bit -static __always_inline void -arch___clear_bit(unsigned int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - - *p &= ~mask; -} +#define arch___clear_bit generic___clear_bit #define __clear_bit arch___clear_bit -/** - * arch___change_bit - Toggle a bit in memory - * @nr: the bit to change - * @addr: the address to start counting from - * - * Unlike change_bit(), this function is non-atomic and may be reordered. - * If it's called on the same region of memory simultaneously, the effect - * may be that only one operation succeeds. - */ -static __always_inline -void arch___change_bit(unsigned int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - - *p ^= mask; -} +#define arch___change_bit generic___change_bit #define __change_bit arch___change_bit -/** - * arch___test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is non-atomic and can be reordered. - * If two examples of this operation race, one can appear to succeed - * but actually fail. You must protect multiple accesses with a lock. - */ -static __always_inline int -arch___test_and_set_bit(unsigned int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - unsigned long old = *p; - - *p = old | mask; - return (old & mask) != 0; -} +#define arch___test_and_set_bit generic___test_and_set_bit #define __test_and_set_bit arch___test_and_set_bit -/** - * arch___test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to clear - * @addr: Address to count from - * - * This operation is non-atomic and can be reordered. - * If two examples of this operation race, one can appear to succeed - * but actually fail. You must protect multiple accesses with a lock. - */ -static __always_inline int -arch___test_and_clear_bit(unsigned int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - unsigned long old = *p; - - *p = old & ~mask; - return (old & mask) != 0; -} +#define arch___test_and_clear_bit generic___test_and_clear_bit #define __test_and_clear_bit arch___test_and_clear_bit -/* WARNING: non atomic and it can be reordered! */ -static __always_inline int -arch___test_and_change_bit(unsigned int nr, volatile unsigned long *addr) -{ - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); - unsigned long old = *p; - - *p = old ^ mask; - return (old & mask) != 0; -} +#define arch___test_and_change_bit generic___test_and_change_bit #define __test_and_change_bit arch___test_and_change_bit -/** - * arch_test_bit - Determine whether a bit is set - * @nr: bit number to test - * @addr: Address to start counting from - */ -static __always_inline int -arch_test_bit(unsigned int nr, const volatile unsigned long *addr) -{ - return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); -} +#define arch_test_bit generic_test_bit #define test_bit arch_test_bit #endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */