summaryrefslogtreecommitdiff
path: root/fs/btrfs/locking.c
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2024-03-18 11:08:30 +0000
committerDavid Sterba <dsterba@suse.com>2024-05-07 21:31:00 +0200
commitc79f57eafc5e01190fa05f2de8cbd5f579d68acd (patch)
treef8dc60260d1a8c40530c87df5ddae1a40f028a2b /fs/btrfs/locking.c
parentc66f2afc714867cf7e685680d848748e0d636bef (diff)
downloadlwn-c79f57eafc5e01190fa05f2de8cbd5f579d68acd.tar.gz
lwn-c79f57eafc5e01190fa05f2de8cbd5f579d68acd.zip
btrfs: avoid pointless wake ups of drew lock readers
When unlocking a write lock on a drew lock, at btrfs_drew_write_unlock(), it's pointless to wake up tasks waiting to acquire a read lock if we didn't decrement the 'writers' counter down to 0, since a read lock can only be acquired when the counter reaches a value of 0. Doing so is harmless from a functional point of view, but it's not efficient due to unnecessarily waking up tasks just for them to sleep again on the waitqueue. So change this to wake up readers only if we decremented the 'writers' counter to 0. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/locking.c')
-rw-r--r--fs/btrfs/locking.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index 508a3fdfcd58..72992e74c479 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -364,8 +364,12 @@ void btrfs_drew_write_lock(struct btrfs_drew_lock *lock)
void btrfs_drew_write_unlock(struct btrfs_drew_lock *lock)
{
- atomic_dec(&lock->writers);
- cond_wake_up(&lock->pending_readers);
+ /*
+ * atomic_dec_and_test() implies a full barrier, so woken up readers are
+ * guaranteed to see the decrement.
+ */
+ if (atomic_dec_and_test(&lock->writers))
+ wake_up(&lock->pending_readers);
}
void btrfs_drew_read_lock(struct btrfs_drew_lock *lock)