diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-02-28 14:22:52 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:17 -0400 |
commit | 9ace606e93e9c6dff919ca8f35d461e8462590b7 (patch) | |
tree | 1392da42af426494cff2bd8150a8177799eba548 /fs | |
parent | 03d5eaed8624fdc7918478bffd05d67e773ac7d0 (diff) | |
download | linux-9ace606e93e9c6dff919ca8f35d461e8462590b7.tar.gz linux-9ace606e93e9c6dff919ca8f35d461e8462590b7.tar.bz2 linux-9ace606e93e9c6dff919ca8f35d461e8462590b7.zip |
bcachefs: Don't block on reclaim_lock from journal_res_get
When we're doing btree updates from journal flush, this becomes a
locking inversion
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/journal.c | 5 | ||||
-rw-r--r-- | fs/bcachefs/journal_reclaim.c | 23 | ||||
-rw-r--r-- | fs/bcachefs/journal_reclaim.h | 1 |
3 files changed, 20 insertions, 9 deletions
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index 5caa01881d00..ba6adf11ef42 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -390,7 +390,10 @@ retry: goto retry; } - bch2_journal_reclaim_work(&j->reclaim_work.work); + if (mutex_trylock(&j->reclaim_lock)) { + bch2_journal_reclaim(j); + mutex_unlock(&j->reclaim_lock); + } } ret = -EAGAIN; diff --git a/fs/bcachefs/journal_reclaim.c b/fs/bcachefs/journal_reclaim.c index 0884fc823cdf..a3c53b78ad10 100644 --- a/fs/bcachefs/journal_reclaim.c +++ b/fs/bcachefs/journal_reclaim.c @@ -433,7 +433,7 @@ static void journal_flush_pins(struct journal *j, u64 seq_to_flush, } /** - * bch2_journal_reclaim_work - free up journal buckets + * bch2_journal_reclaim - free up journal buckets * * Background journal reclaim writes out btree nodes. It should be run * early enough so that we never completely run out of journal buckets. @@ -450,18 +450,17 @@ static void journal_flush_pins(struct journal *j, u64 seq_to_flush, * 512 journal entries or 25% of all journal buckets, then * journal_next_bucket() should not stall. */ -void bch2_journal_reclaim_work(struct work_struct *work) +void bch2_journal_reclaim(struct journal *j) { - struct bch_fs *c = container_of(to_delayed_work(work), - struct bch_fs, journal.reclaim_work); - struct journal *j = &c->journal; + struct bch_fs *c = container_of(j, struct bch_fs, journal); struct bch_dev *ca; unsigned iter, bucket_to_flush, min_nr = 0; u64 seq_to_flush = 0; + lockdep_assert_held(&j->reclaim_lock); + bch2_journal_do_discards(j); - mutex_lock(&j->reclaim_lock); spin_lock(&j->lock); for_each_rw_member(ca, c, iter) { @@ -493,13 +492,21 @@ void bch2_journal_reclaim_work(struct work_struct *work) journal_flush_pins(j, seq_to_flush, min_nr); - mutex_unlock(&j->reclaim_lock); - if (!test_bit(BCH_FS_RO, &c->flags)) queue_delayed_work(c->journal_reclaim_wq, &j->reclaim_work, msecs_to_jiffies(j->reclaim_delay_ms)); } +void bch2_journal_reclaim_work(struct work_struct *work) +{ + struct journal *j = container_of(to_delayed_work(work), + struct journal, reclaim_work); + + mutex_lock(&j->reclaim_lock); + bch2_journal_reclaim(j); + mutex_unlock(&j->reclaim_lock); +} + static int journal_flush_done(struct journal *j, u64 seq_to_flush) { int ret; diff --git a/fs/bcachefs/journal_reclaim.h b/fs/bcachefs/journal_reclaim.h index 71545ad3bd58..9bf982a17797 100644 --- a/fs/bcachefs/journal_reclaim.h +++ b/fs/bcachefs/journal_reclaim.h @@ -42,6 +42,7 @@ void bch2_journal_pin_add_if_older(struct journal *, void bch2_journal_pin_flush(struct journal *, struct journal_entry_pin *); void bch2_journal_do_discards(struct journal *); +void bch2_journal_reclaim(struct journal *); void bch2_journal_reclaim_work(struct work_struct *); void bch2_journal_flush_pins(struct journal *, u64); |