diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-06-16 22:00:48 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-23 00:10:02 +0300 |
commit | dc88b65f3e54b5f25dcfe1259ae21c19a6e69d7f (patch) | |
tree | ebff7bfc8448bf85dafcd47ae556828a9a5b3124 /fs/bcachefs/six.c | |
parent | 37f612bea5bd921e71537df3559a117dffb0956d (diff) | |
download | linux-dc88b65f3e54b5f25dcfe1259ae21c19a6e69d7f.tar.xz |
six locks: Simplify six_relock()
The next patch is going to move lock->seq out of lock->state. This
replaces six_relock() with a much simpler implementation based on
trylock.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/six.c')
-rw-r--r-- | fs/bcachefs/six.c | 47 |
1 files changed, 5 insertions, 42 deletions
diff --git a/fs/bcachefs/six.c b/fs/bcachefs/six.c index fcc74e626db0..3fb5959fe40f 100644 --- a/fs/bcachefs/six.c +++ b/fs/bcachefs/six.c @@ -409,51 +409,14 @@ EXPORT_SYMBOL_GPL(six_trylock_ip); bool six_relock_ip(struct six_lock *lock, enum six_lock_type type, unsigned seq, unsigned long ip) { - const struct six_lock_vals l[] = LOCK_VALS; - u64 old, v; - - EBUG_ON(type == SIX_LOCK_write); - - if (type == SIX_LOCK_read && - lock->readers) { - bool ret; - - preempt_disable(); - this_cpu_inc(*lock->readers); - - smp_mb(); - - old = atomic64_read(&lock->state); - ret = !(old & l[type].lock_fail) && six_state_seq(old) == seq; - - this_cpu_sub(*lock->readers, !ret); - preempt_enable(); - - /* - * Similar to the lock path, we may have caused a spurious write - * lock fail and need to issue a wakeup: - */ - if (ret) - six_acquire(&lock->dep_map, 1, type == SIX_LOCK_read, ip); - else if (old & SIX_STATE_WAITING_WRITE) - six_lock_wakeup(lock, old, SIX_LOCK_write); + if (six_lock_seq(lock) != seq || !six_trylock_ip(lock, type, ip)) + return false; - return ret; + if (six_lock_seq(lock) != seq) { + six_unlock_ip(lock, type, ip); + return false; } - v = atomic64_read(&lock->state); - do { - old = v; - - if ((old & l[type].lock_fail) || six_state_seq(old) != seq) - return false; - } while ((v = atomic64_cmpxchg_acquire(&lock->state, - old, - old + l[type].lock_val)) != old); - - six_set_owner(lock, type, old, current); - if (type != SIX_LOCK_write) - six_acquire(&lock->dep_map, 1, type == SIX_LOCK_read, ip); return true; } EXPORT_SYMBOL_GPL(six_relock_ip); |