bcachefs: Data move path now uses bch2_trans_unlock_long()
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 30 Oct 2023 19:13:09 +0000 (15:13 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 5 Nov 2023 02:19:11 +0000 (22:19 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_iter.c
fs/bcachefs/move.c
fs/bcachefs/move.h
fs/bcachefs/movinggc.c
fs/bcachefs/rebalance.c

index b22fd395a1fd7dca494aecb90a490f4fe424b4ac..af98545e0f352ba89f5a31dd6fc70b7ee213ee71 100644 (file)
@@ -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);
 
index 1b15b010461ae19b7b52dfda1f7bcbcbad63bb93..ab749bf2fcbc551e68753857efdf008848d140b7 100644 (file)
@@ -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);
                }
 
index 1b1e8678bfaef452f3d8ccd456fc679bdc8b46c5..07cf9d42643b4fe537b6db513285efc1f65bd366 100644 (file)
@@ -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)));                        \
index e0efa5282a77eb2b6bcc2b55104347daf5927694..4d955f3cc5b235c76ca9a24482e5806731ea4925 100644 (file)
@@ -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) {
index 82014cc6e271b0e302a30cc51696bdae00ffeafd..3319190b8d9c330fde44ad959bc299aa00d2ba87 100644 (file)
@@ -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);
        }