bcachefs: Avoid spurious transaction restarts
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 15 May 2019 14:08:55 +0000 (10:08 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:22 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.h
fs/bcachefs/fs.c

index cbf9281e195bcd7cff9062bd855b846f45648624..b058b6f3b89dffb8d2a216c1c4d6f441654210f0 100644 (file)
@@ -160,7 +160,7 @@ success:
 }
 
 static inline bool btree_iter_get_locks(struct btree_iter *iter,
-                                       bool upgrade)
+                                       bool upgrade, bool trace)
 {
        unsigned l = iter->level;
        int fail_idx = -1;
@@ -172,16 +172,10 @@ static inline bool btree_iter_get_locks(struct btree_iter *iter,
                if (!(upgrade
                      ? bch2_btree_node_upgrade(iter, l)
                      : bch2_btree_node_relock(iter, l))) {
-                       if (upgrade)
-                               trace_node_upgrade_fail(l, iter->l[l].lock_seq,
-                                               is_btree_node(iter, l)
-                                               ? 0
-                                               : (unsigned long) iter->l[l].b,
-                                               is_btree_node(iter, l)
-                                               ? iter->l[l].b->c.lock.state.seq
-                                               : 0);
-                       else
-                               trace_node_relock_fail(l, iter->l[l].lock_seq,
+                       if (trace)
+                               (upgrade
+                                ? trace_node_upgrade_fail
+                                : trace_node_relock_fail)(l, iter->l[l].lock_seq,
                                                is_btree_node(iter, l)
                                                ? 0
                                                : (unsigned long) iter->l[l].b,
@@ -251,7 +245,7 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos,
                                linked->locks_want = max_t(unsigned,
                                                linked->locks_want,
                                                __fls(linked->nodes_locked) + 1);
-                               btree_iter_get_locks(linked, true);
+                               btree_iter_get_locks(linked, true, false);
                        }
                        ret = false;
                }
@@ -268,7 +262,7 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos,
                                        max(level + 1, max_t(unsigned,
                                            linked->locks_want,
                                            iter->locks_want));
-                               btree_iter_get_locks(linked, true);
+                               btree_iter_get_locks(linked, true, false);
                        }
                        ret = false;
                }
@@ -312,10 +306,10 @@ void bch2_btree_trans_verify_locks(struct btree_trans *trans)
 #endif
 
 __flatten
-static bool bch2_btree_iter_relock(struct btree_iter *iter)
+static bool bch2_btree_iter_relock(struct btree_iter *iter, bool trace)
 {
        return iter->uptodate >= BTREE_ITER_NEED_RELOCK
-               ? btree_iter_get_locks(iter, false)
+               ? btree_iter_get_locks(iter, false, trace)
                : true;
 }
 
@@ -328,7 +322,7 @@ bool __bch2_btree_iter_upgrade(struct btree_iter *iter,
 
        iter->locks_want = new_locks_want;
 
-       if (btree_iter_get_locks(iter, true))
+       if (btree_iter_get_locks(iter, true, true))
                return true;
 
        /*
@@ -341,7 +335,7 @@ bool __bch2_btree_iter_upgrade(struct btree_iter *iter,
                    linked->btree_id == iter->btree_id &&
                    linked->locks_want < new_locks_want) {
                        linked->locks_want = new_locks_want;
-                       btree_iter_get_locks(linked, true);
+                       btree_iter_get_locks(linked, true, false);
                }
 
        return false;
@@ -416,7 +410,8 @@ bool bch2_trans_relock(struct btree_trans *trans)
        bool ret = true;
 
        trans_for_each_iter(trans, iter)
-               ret &= bch2_btree_iter_relock(iter);
+               if (iter->uptodate == BTREE_ITER_NEED_RELOCK)
+                       ret &= bch2_btree_iter_relock(iter, true);
 
        return ret;
 }
@@ -1061,7 +1056,7 @@ int __must_check __bch2_btree_iter_traverse(struct btree_iter *iter)
        if (unlikely(iter->level >= BTREE_MAX_DEPTH))
                return 0;
 
-       if (bch2_btree_iter_relock(iter))
+       if (bch2_btree_iter_relock(iter, false))
                return 0;
 
        /*
@@ -1672,11 +1667,13 @@ int bch2_trans_iter_free_on_commit(struct btree_trans *trans,
        return ret;
 }
 
-static int btree_trans_realloc_iters(struct btree_trans *trans,
-                                    unsigned new_size)
+int bch2_trans_realloc_iters(struct btree_trans *trans,
+                                   unsigned new_size)
 {
        void *new_iters, *new_updates;
 
+       new_size = roundup_pow_of_two(new_size);
+
        BUG_ON(new_size > BTREE_ITER_MAX);
 
        if (new_size <= trans->size)
@@ -1727,7 +1724,7 @@ success:
 
 void bch2_trans_preload_iters(struct btree_trans *trans)
 {
-       btree_trans_realloc_iters(trans, BTREE_ITER_MAX);
+       bch2_trans_realloc_iters(trans, BTREE_ITER_MAX);
 }
 
 static int btree_trans_iter_alloc(struct btree_trans *trans)
@@ -1738,7 +1735,7 @@ static int btree_trans_iter_alloc(struct btree_trans *trans)
                goto got_slot;
 
        if (trans->nr_iters == trans->size) {
-               int ret = btree_trans_realloc_iters(trans, trans->size * 2);
+               int ret = bch2_trans_realloc_iters(trans, trans->size * 2);
                if (ret)
                        return ret;
        }
index ee2cea2b0b44679be60da9e8c5cdabecb87466a6..3089aa7cf8e93f084745982697d93e66a77ab22c 100644 (file)
@@ -258,7 +258,9 @@ static inline int bkey_err(struct bkey_s_c k)
 
 /* new multiple iterator interface: */
 
+int bch2_trans_realloc_iters(struct btree_trans *, unsigned);
 void bch2_trans_preload_iters(struct btree_trans *);
+
 int bch2_trans_iter_put(struct btree_trans *, struct btree_iter *);
 int bch2_trans_iter_free(struct btree_trans *, struct btree_iter *);
 int bch2_trans_iter_free_on_commit(struct btree_trans *, struct btree_iter *);
index aac59b8a15eb6c7c14ca67876f7f09c758c14bec..b5a025939f51816092f16d2e334fb526a9679f2f 100644 (file)
@@ -415,6 +415,7 @@ __bch2_create(struct mnt_idmap *idmap,
                mutex_lock(&dir->ei_update_lock);
 
        bch2_trans_init(&trans, c);
+       bch2_trans_realloc_iters(&trans, 8);
 retry:
        bch2_trans_begin(&trans);