summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-05-15 10:08:55 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2019-06-10 14:08:06 -0400
commit825dfb04049cc57ecbb830579942f3f555ccfe45 (patch)
tree5869826804bb86b206b70892a8bf1d5876515bb5
parent070bd78602c3a381bdb636dd581f0df272a7c3b1 (diff)
bcachefs: Avoid spurious transaction restarts
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/btree_iter.c43
-rw-r--r--fs/bcachefs/btree_iter.h2
-rw-r--r--fs/bcachefs/fs.c1
3 files changed, 23 insertions, 23 deletions
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index d8c212ed4b33..20601d364ed9 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -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->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;
}
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
index 5fd274f40016..a0e428eb0319 100644
--- a/fs/bcachefs/btree_iter.h
+++ b/fs/bcachefs/btree_iter.h
@@ -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 *);
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index cce1616559a3..35ec7cce6911 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -357,6 +357,7 @@ __bch2_create(struct bch_inode_info *dir, struct dentry *dentry,
mutex_lock(&dir->ei_update_lock);
bch2_trans_init(&trans, c);
+ bch2_trans_realloc_iters(&trans, 8);
retry:
bch2_trans_begin(&trans);