mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 02:34:10 -04:00
bcachefs: Don't make foreground writes wait behind journal reclaim too long
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
committed by
Kent Overstreet
parent
65bcd6579d
commit
24db24c749
@@ -586,6 +586,28 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int journal_reclaim_wait_done(struct bch_fs *c)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bch2_journal_error(&c->journal);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = !bch2_btree_key_cache_must_wait(c);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mutex_trylock(&c->journal.reclaim_lock)) {
|
||||
ret = bch2_journal_reclaim(&c->journal);
|
||||
mutex_unlock(&c->journal.reclaim_lock);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
ret = !bch2_btree_key_cache_must_wait(c);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static noinline
|
||||
int bch2_trans_commit_error(struct btree_trans *trans,
|
||||
struct btree_insert_entry *i,
|
||||
@@ -668,13 +690,12 @@ int bch2_trans_commit_error(struct btree_trans *trans,
|
||||
case BTREE_INSERT_NEED_JOURNAL_RECLAIM:
|
||||
bch2_trans_unlock(trans);
|
||||
|
||||
do {
|
||||
mutex_lock(&c->journal.reclaim_lock);
|
||||
ret = bch2_journal_reclaim(&c->journal);
|
||||
mutex_unlock(&c->journal.reclaim_lock);
|
||||
} while (!ret && bch2_btree_key_cache_must_wait(c));
|
||||
wait_event(c->journal.reclaim_wait,
|
||||
(ret = journal_reclaim_wait_done(c)));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!ret && bch2_trans_relock(trans))
|
||||
if (bch2_trans_relock(trans))
|
||||
return 0;
|
||||
|
||||
trace_trans_restart_journal_reclaim(trans->ip);
|
||||
|
||||
@@ -1116,6 +1116,7 @@ int bch2_fs_journal_init(struct journal *j)
|
||||
spin_lock_init(&j->err_lock);
|
||||
init_waitqueue_head(&j->wait);
|
||||
INIT_DELAYED_WORK(&j->write_work, journal_write_work);
|
||||
init_waitqueue_head(&j->reclaim_wait);
|
||||
init_waitqueue_head(&j->pin_flush_wait);
|
||||
mutex_init(&j->reclaim_lock);
|
||||
mutex_init(&j->discard_lock);
|
||||
|
||||
@@ -604,6 +604,9 @@ static int __bch2_journal_reclaim(struct journal *j, bool direct)
|
||||
|
||||
min_nr = max(min_nr, bch2_nr_btree_keys_want_flush(c));
|
||||
|
||||
/* Don't do too many without delivering wakeup: */
|
||||
min_nr = min(min_nr, 128UL);
|
||||
|
||||
trace_journal_reclaim_start(c,
|
||||
min_nr,
|
||||
j->prereserved.reserved,
|
||||
@@ -620,6 +623,9 @@ static int __bch2_journal_reclaim(struct journal *j, bool direct)
|
||||
else
|
||||
j->nr_background_reclaim += nr_flushed;
|
||||
trace_journal_reclaim_finish(c, nr_flushed);
|
||||
|
||||
if (nr_flushed)
|
||||
wake_up(&j->reclaim_wait);
|
||||
} while (min_nr && nr_flushed);
|
||||
|
||||
memalloc_noreclaim_restore(flags);
|
||||
|
||||
@@ -243,6 +243,7 @@ struct journal {
|
||||
spinlock_t err_lock;
|
||||
|
||||
struct mutex reclaim_lock;
|
||||
wait_queue_head_t reclaim_wait;
|
||||
struct task_struct *reclaim_thread;
|
||||
bool reclaim_kicked;
|
||||
u64 nr_direct_reclaim;
|
||||
|
||||
Reference in New Issue
Block a user