Commit 24db24c7 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Don't make foreground writes wait behind journal reclaim too long

Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 65bcd657
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment