Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 
0003 /*
0004  * This file provides wrappers with sanitizer instrumentation for bit
0005  * locking operations.
0006  *
0007  * To use this functionality, an arch's bitops.h file needs to define each of
0008  * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
0009  * arch___set_bit(), etc.).
0010  */
0011 #ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
0012 #define _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
0013 
0014 #include <linux/instrumented.h>
0015 
0016 /**
0017  * clear_bit_unlock - Clear a bit in memory, for unlock
0018  * @nr: the bit to set
0019  * @addr: the address to start counting from
0020  *
0021  * This operation is atomic and provides release barrier semantics.
0022  */
0023 static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
0024 {
0025     kcsan_release();
0026     instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
0027     arch_clear_bit_unlock(nr, addr);
0028 }
0029 
0030 /**
0031  * __clear_bit_unlock - Clears a bit in memory
0032  * @nr: Bit to clear
0033  * @addr: Address to start counting from
0034  *
0035  * This is a non-atomic operation but implies a release barrier before the
0036  * memory operation. It can be used for an unlock if no other CPUs can
0037  * concurrently modify other bits in the word.
0038  */
0039 static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
0040 {
0041     kcsan_release();
0042     instrument_write(addr + BIT_WORD(nr), sizeof(long));
0043     arch___clear_bit_unlock(nr, addr);
0044 }
0045 
0046 /**
0047  * test_and_set_bit_lock - Set a bit and return its old value, for lock
0048  * @nr: Bit to set
0049  * @addr: Address to count from
0050  *
0051  * This operation is atomic and provides acquire barrier semantics if
0052  * the returned value is 0.
0053  * It can be used to implement bit locks.
0054  */
0055 static inline bool test_and_set_bit_lock(long nr, volatile unsigned long *addr)
0056 {
0057     instrument_atomic_read_write(addr + BIT_WORD(nr), sizeof(long));
0058     return arch_test_and_set_bit_lock(nr, addr);
0059 }
0060 
0061 #if defined(arch_clear_bit_unlock_is_negative_byte)
0062 /**
0063  * clear_bit_unlock_is_negative_byte - Clear a bit in memory and test if bottom
0064  *                                     byte is negative, for unlock.
0065  * @nr: the bit to clear
0066  * @addr: the address to start counting from
0067  *
0068  * This operation is atomic and provides release barrier semantics.
0069  *
0070  * This is a bit of a one-trick-pony for the filemap code, which clears
0071  * PG_locked and tests PG_waiters,
0072  */
0073 static inline bool
0074 clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
0075 {
0076     kcsan_release();
0077     instrument_atomic_write(addr + BIT_WORD(nr), sizeof(long));
0078     return arch_clear_bit_unlock_is_negative_byte(nr, addr);
0079 }
0080 /* Let everybody know we have it. */
0081 #define clear_bit_unlock_is_negative_byte clear_bit_unlock_is_negative_byte
0082 #endif
0083 
0084 #endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H */