bcachefs: Drop all btree locks when submitting btree node reads
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 9 Apr 2021 02:26:53 +0000 (22:26 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:05 +0000 (17:09 -0400)
As a rule we don't want to be holding btree locks while submitting IO -
this will improve overall filesystem latency.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/btree_cache.c
fs/bcachefs/btree_iter.c

index 5991ebee228c87d9188e602c3fb56ea1a53b670f..15f597ab03e7cdfc9ec9d26ac338d125b8cdc056 100644 (file)
@@ -663,13 +663,9 @@ static noinline struct btree *bch2_btree_node_fill(struct bch_fs *c,
                return NULL;
        }
 
-       /*
-        * Unlock before doing IO:
-        *
-        * XXX: ideally should be dropping all btree node locks here
-        */
-       if (iter && btree_node_read_locked(iter, level + 1))
-               btree_node_unlock(iter, level + 1);
+       /* Unlock before doing IO: */
+       if (iter && sync)
+               bch2_trans_unlock(iter->trans);
 
        bch2_btree_node_read(c, b, sync);
 
@@ -680,6 +676,16 @@ static noinline struct btree *bch2_btree_node_fill(struct bch_fs *c,
                return NULL;
        }
 
+       /*
+        * XXX: this will probably always fail because btree_iter_relock()
+        * currently fails for iterators that aren't pointed at a valid btree
+        * node
+        */
+       if (iter && !bch2_trans_relock(iter->trans)) {
+               six_unlock_intent(&b->c.lock);
+               return ERR_PTR(-EINTR);
+       }
+
        if (lock_type == SIX_LOCK_read)
                six_lock_downgrade(&b->c.lock);
 
@@ -824,9 +830,22 @@ lock_node:
                }
        }
 
-       /* XXX: waiting on IO with btree locks held: */
-       wait_on_bit_io(&b->flags, BTREE_NODE_read_in_flight,
-                      TASK_UNINTERRUPTIBLE);
+       if (unlikely(btree_node_read_in_flight(b))) {
+               six_unlock_type(&b->c.lock, lock_type);
+               bch2_trans_unlock(iter->trans);
+
+               wait_on_bit_io(&b->flags, BTREE_NODE_read_in_flight,
+                              TASK_UNINTERRUPTIBLE);
+
+               /*
+                * XXX: check if this always fails - btree_iter_relock()
+                * currently fails for iterators that aren't pointed at a valid
+                * btree node
+                */
+               if (iter && !bch2_trans_relock(iter->trans))
+                       return ERR_PTR(-EINTR);
+               goto retry;
+       }
 
        prefetch(b->aux_data);
 
index 17338410d1fe7be2da9881993506c27a212cefb5..5c38562ab206e5c7788af8fba14e757213012287 100644 (file)
@@ -1191,7 +1191,11 @@ static __always_inline int btree_iter_down(struct btree_iter *iter,
        if (iter->flags & BTREE_ITER_PREFETCH)
                btree_iter_prefetch(iter);
 
+       if (btree_node_read_locked(iter, level + 1))
+               btree_node_unlock(iter, level + 1);
        iter->level = level;
+
+       bch2_btree_iter_verify_locks(iter);
 err:
        bch2_bkey_buf_exit(&tmp, c);
        return ret;