diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-05-22 17:54:19 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:10:02 -0400 |
commit | 357c1261526db604dd4593638620a801c44d02bd (patch) | |
tree | bacae0f0a7ae3b2686878d51efa82427728d5f59 /fs/bcachefs/six.c | |
parent | b60c8e9e7b082abac290ebdb9166b806e7d83fb7 (diff) | |
download | linux-357c1261526db604dd4593638620a801c44d02bd.tar.gz linux-357c1261526db604dd4593638620a801c44d02bd.tar.bz2 linux-357c1261526db604dd4593638620a801c44d02bd.zip |
six_locks: Kill test_bit()/set_bit() usage
This deletes the crazy cast-atomic-to-unsigned-long, and replaces them
with atomic_and() and atomic_or().
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/six.c')
-rw-r--r-- | fs/bcachefs/six.c | 63 |
1 files changed, 4 insertions, 59 deletions
diff --git a/fs/bcachefs/six.c b/fs/bcachefs/six.c index e566c429607b..266ee5d95479 100644 --- a/fs/bcachefs/six.c +++ b/fs/bcachefs/six.c @@ -96,73 +96,18 @@ static inline u32 six_state_seq(u64 state) return state >> SIX_STATE_SEQ_OFFSET; } -#ifdef CONFIG_GENERIC_ATOMIC64 - static inline void six_set_bitmask(struct six_lock *lock, u64 mask) { - u64 old, new, v = atomic64_read(&lock->state); - - do { - old = new = v; - if ((old & mask) == mask) - break; - new |= mask; - } while ((v = atomic64_cmpxchg(&lock->state, old, new)) != old); + if ((atomic64_read(&lock->state) & mask) != mask) + atomic64_or(mask, &lock->state); } static inline void six_clear_bitmask(struct six_lock *lock, u64 mask) { - u64 old, new, v = atomic64_read(&lock->state); - - do { - old = new = v; - if (!(old & mask)) - break; - new &= ~mask; - } while ((v = atomic64_cmpxchg(&lock->state, old, new)) != old); + if (atomic64_read(&lock->state) & mask) + atomic64_and(~mask, &lock->state); } -#else - -/* - * Returns the index of the first set bit, treating @mask as an array of ulongs: - * that is, a bit index that can be passed to test_bit()/set_bit(). - * - * Assumes the set bit we want is in the low 4 bytes: - */ -static inline unsigned u64_mask_to_ulong_bitnr(u64 mask) -{ -#if BITS_PER_LONG == 64 - return ilog2(mask); -#else -#if defined(__LITTLE_ENDIAN) - return ilog2((u32) mask); -#elif defined(__BIG_ENDIAN) - return ilog2((u32) mask) + 32; -#else -#error Unknown byteorder -#endif -#endif -} - -static inline void six_set_bitmask(struct six_lock *lock, u64 mask) -{ - unsigned bitnr = u64_mask_to_ulong_bitnr(mask); - - if (!test_bit(bitnr, (unsigned long *) &lock->state)) - set_bit(bitnr, (unsigned long *) &lock->state); -} - -static inline void six_clear_bitmask(struct six_lock *lock, u64 mask) -{ - unsigned bitnr = u64_mask_to_ulong_bitnr(mask); - - if (test_bit(bitnr, (unsigned long *) &lock->state)) - clear_bit(bitnr, (unsigned long *) &lock->state); -} - -#endif - static inline void six_set_owner(struct six_lock *lock, enum six_lock_type type, u64 old, struct task_struct *owner) { |