aboutsummaryrefslogtreecommitdiff
path: root/fs/bcachefs/six.c
diff options
context:
space:
mode:
authorGravatar Kent Overstreet <kent.overstreet@linux.dev> 2023-06-16 15:00:48 -0400
committerGravatar Kent Overstreet <kent.overstreet@linux.dev> 2023-10-22 17:10:02 -0400
commitdc88b65f3e54b5f25dcfe1259ae21c19a6e69d7f (patch)
treeebff7bfc8448bf85dafcd47ae556828a9a5b3124 /fs/bcachefs/six.c
parentsix locks: Improve spurious wakeup handling in pcpu reader mode (diff)
downloadlinux-dc88b65f3e54b5f25dcfe1259ae21c19a6e69d7f.tar.gz
linux-dc88b65f3e54b5f25dcfe1259ae21c19a6e69d7f.tar.bz2
linux-dc88b65f3e54b5f25dcfe1259ae21c19a6e69d7f.zip
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.c47
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);