From f82755e4e8b83a4a98ebd6d819d716547fe11919 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 30 Oct 2023 15:13:09 -0400 Subject: [PATCH] bcachefs: Data move path now uses bch2_trans_unlock_long() Signed-off-by: Kent Overstreet --- fs/bcachefs/btree_iter.c | 12 +++++++++++- fs/bcachefs/move.c | 13 ++++++++----- fs/bcachefs/move.h | 1 + fs/bcachefs/movinggc.c | 4 ++-- fs/bcachefs/rebalance.c | 2 +- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index b22fd395a1fd..af98545e0f35 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -2833,6 +2833,13 @@ void *__bch2_trans_kmalloc(struct btree_trans *trans, size_t size) return p; } +static inline void check_srcu_held_too_long(struct btree_trans *trans) +{ + WARN(trans->srcu_held && time_after(jiffies, trans->srcu_lock_time + HZ * 10), + "btree trans held srcu lock (delaying memory reclaim) for %lu seconds", + (jiffies - trans->srcu_lock_time) / HZ); +} + void bch2_trans_srcu_unlock(struct btree_trans *trans) { if (trans->srcu_held) { @@ -2843,6 +2850,7 @@ void bch2_trans_srcu_unlock(struct btree_trans *trans) if (path->cached && !btree_node_locked(path, 0)) path->l[0].b = ERR_PTR(-BCH_ERR_no_btree_node_srcu_reset); + check_srcu_held_too_long(trans); srcu_read_unlock(&c->btree_trans_barrier, trans->srcu_idx); trans->srcu_held = false; } @@ -3074,8 +3082,10 @@ void bch2_trans_put(struct btree_trans *trans) check_btree_paths_leaked(trans); - if (trans->srcu_held) + if (trans->srcu_held) { + check_srcu_held_too_long(trans); srcu_read_unlock(&c->btree_trans_barrier, trans->srcu_idx); + } bch2_journal_preres_put(&c->journal, &trans->journal_preres); diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index 1b15b010461a..ab749bf2fcbc 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -147,9 +147,8 @@ void bch2_moving_ctxt_do_pending_writes(struct moving_context *ctxt) { struct moving_io *io; - bch2_trans_unlock(ctxt->trans); - while ((io = bch2_moving_ctxt_next_pending_write(ctxt))) { + bch2_trans_unlock_long(ctxt->trans); list_del(&io->read_list); move_write(io); } @@ -485,8 +484,8 @@ int bch2_move_ratelimit(struct moving_context *ctxt) struct bch_fs *c = ctxt->trans->c; u64 delay; - if (ctxt->wait_on_copygc) { - bch2_trans_unlock(ctxt->trans); + if (ctxt->wait_on_copygc && !c->copygc_running) { + bch2_trans_unlock_long(ctxt->trans); wait_event_killable(c->copygc_running_wq, !c->copygc_running || kthread_should_stop()); @@ -495,8 +494,12 @@ int bch2_move_ratelimit(struct moving_context *ctxt) do { delay = ctxt->rate ? bch2_ratelimit_delay(ctxt->rate) : 0; + if (delay) { - bch2_trans_unlock(ctxt->trans); + if (delay > HZ / 10) + bch2_trans_unlock_long(ctxt->trans); + else + bch2_trans_unlock(ctxt->trans); set_current_state(TASK_INTERRUPTIBLE); } diff --git a/fs/bcachefs/move.h b/fs/bcachefs/move.h index 1b1e8678bfae..07cf9d42643b 100644 --- a/fs/bcachefs/move.h +++ b/fs/bcachefs/move.h @@ -45,6 +45,7 @@ do { \ \ if (_cond) \ break; \ + bch2_trans_unlock_long((_ctxt)->trans); \ __wait_event((_ctxt)->wait, \ bch2_moving_ctxt_next_pending_write(_ctxt) || \ (cond_finished = (_cond))); \ diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c index e0efa5282a77..4d955f3cc5b2 100644 --- a/fs/bcachefs/movinggc.c +++ b/fs/bcachefs/movinggc.c @@ -128,7 +128,7 @@ static void move_buckets_wait(struct moving_context *ctxt, kfree(i); } - bch2_trans_unlock(ctxt->trans); + bch2_trans_unlock_long(ctxt->trans); } static bool bucket_in_flight(struct buckets_in_flight *list, @@ -327,7 +327,7 @@ static int bch2_copygc_thread(void *arg) while (!ret && !kthread_should_stop()) { bool did_work = false; - bch2_trans_unlock(ctxt.trans); + bch2_trans_unlock_long(ctxt.trans); cond_resched(); if (!c->copy_gc_enabled) { diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c index 82014cc6e271..3319190b8d9c 100644 --- a/fs/bcachefs/rebalance.c +++ b/fs/bcachefs/rebalance.c @@ -348,7 +348,7 @@ static int do_rebalance(struct moving_context *ctxt) !kthread_should_stop() && !atomic64_read(&r->work_stats.sectors_seen) && !atomic64_read(&r->scan_stats.sectors_seen)) { - bch2_trans_unlock(trans); + bch2_trans_unlock_long(trans); rebalance_wait(c); }