Commit 7d825866 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Avoid spurious transaction restarts

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