summaryrefslogtreecommitdiff
path: root/fs/bcachefs/buckets.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-12-03 14:17:33 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:21 -0400
commitfca1223ccfac2a461d7d3e29fb09a1b2142bdd7f (patch)
tree532c8e13a14d3f2e39c6df1fe019544f7db51cf3 /fs/bcachefs/buckets.c
parent33eb63e5753ad6229d4027340153817b92840760 (diff)
downloadlwn-fca1223ccfac2a461d7d3e29fb09a1b2142bdd7f.tar.gz
lwn-fca1223ccfac2a461d7d3e29fb09a1b2142bdd7f.zip
bcachefs: Avoid write lock on mark_lock
mark_lock is a frequently taken lock, and there's also potential for deadlocks since currently bch2_clear_page_bits which is called from memory reclaim has to take it to drop disk reservations. The disk reservation get path takes it when it recalculates the number of sectors known to be available, but it's not really needed for consistency. We just want to make sure we only have one thread updating the sectors_available count, which we can do with a dedicated mutex. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/buckets.c')
-rw-r--r--fs/bcachefs/buckets.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
index ff4c61371830..2488a2227bd9 100644
--- a/fs/bcachefs/buckets.c
+++ b/fs/bcachefs/buckets.c
@@ -1182,13 +1182,6 @@ void bch2_trans_fs_usage_apply(struct btree_trans *trans,
/* Disk reservations: */
-static u64 bch2_recalc_sectors_available(struct bch_fs *c)
-{
- percpu_u64_set(&c->pcpu->sectors_available, 0);
-
- return avail_factor(__bch2_fs_usage_read_short(c).free);
-}
-
void __bch2_disk_reservation_put(struct bch_fs *c, struct disk_reservation *res)
{
percpu_down_read(&c->mark_lock);
@@ -1222,7 +1215,6 @@ int bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
if (get < sectors) {
preempt_enable();
- percpu_up_read(&c->mark_lock);
goto recalculate;
}
} while ((v = atomic64_cmpxchg(&c->sectors_available,
@@ -1240,9 +1232,10 @@ out:
return 0;
recalculate:
- percpu_down_write(&c->mark_lock);
+ mutex_lock(&c->sectors_available_lock);
- sectors_available = bch2_recalc_sectors_available(c);
+ percpu_u64_set(&c->pcpu->sectors_available, 0);
+ sectors_available = avail_factor(__bch2_fs_usage_read_short(c).free);
if (sectors <= sectors_available ||
(flags & BCH_DISK_RESERVATION_NOFAIL)) {
@@ -1256,7 +1249,8 @@ recalculate:
ret = -ENOSPC;
}
- percpu_up_write(&c->mark_lock);
+ mutex_unlock(&c->sectors_available_lock);
+ percpu_up_read(&c->mark_lock);
return ret;
}