aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-07-12 23:30:45 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:07 -0400
commit1c7a0adf3112090c42ef93ac84aad97bf4d414d3 (patch)
tree3a431a138e126ce0950c6f5f54813e692cb437a7 /fs
parentd69f41d6bbd7849253cd823525543bd3a1a307f1 (diff)
bcachefs: trace transaction restarts
exceptionally crappy "tracing", but it's a start at documenting the places restarts can be triggered Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/btree_cache.c1
-rw-r--r--fs/bcachefs/btree_iter.c21
-rw-r--r--fs/bcachefs/btree_iter.h23
-rw-r--r--fs/bcachefs/btree_types.h1
-rw-r--r--fs/bcachefs/btree_update_leaf.c17
5 files changed, 54 insertions, 9 deletions
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c
index f9afae6c710d..3cb3da363d11 100644
--- a/fs/bcachefs/btree_cache.c
+++ b/fs/bcachefs/btree_cache.c
@@ -732,6 +732,7 @@ retry:
if (bch2_btree_node_relock(iter, level + 1))
goto retry;
+ trans_restart();
return ERR_PTR(-EINTR);
}
}
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index 2b4ba41149cf..7bead41b226f 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -263,6 +263,9 @@ bool __bch2_btree_node_lock(struct btree *b, struct bpos pos,
if (ret)
__btree_node_lock_type(c, b, type);
+ else
+ trans_restart();
+
return ret;
}
@@ -1646,7 +1649,12 @@ static int btree_trans_realloc_iters(struct btree_trans *trans)
btree_trans_verify(trans);
- return trans->iters_live ? -EINTR : 0;
+ if (trans->iters_live) {
+ trans_restart();
+ return -EINTR;
+ }
+
+ return 0;
}
int bch2_trans_preload_iters(struct btree_trans *trans)
@@ -1759,8 +1767,10 @@ void *bch2_trans_kmalloc(struct btree_trans *trans,
trans->mem = new_mem;
trans->mem_bytes = new_bytes;
- if (old_bytes)
+ if (old_bytes) {
+ trans_restart();
return ERR_PTR(-EINTR);
+ }
}
ret = trans->mem + trans->mem_top;
@@ -1787,7 +1797,7 @@ int bch2_trans_unlock(struct btree_trans *trans)
return ret;
}
-void bch2_trans_begin(struct btree_trans *trans)
+void __bch2_trans_begin(struct btree_trans *trans)
{
unsigned idx;
@@ -1801,10 +1811,8 @@ void bch2_trans_begin(struct btree_trans *trans)
* further (allocated an iter with a higher idx) than where the iter
* was originally allocated:
*/
- if (!trans->iters_live)
- return;
-
while (trans->iters_linked &&
+ trans->iters_live &&
(idx = __fls(trans->iters_linked)) >
__fls(trans->iters_live)) {
trans->iters_linked ^= 1 << idx;
@@ -1821,6 +1829,7 @@ void bch2_trans_begin(struct btree_trans *trans)
void bch2_trans_init(struct btree_trans *trans, struct bch_fs *c)
{
trans->c = c;
+ trans->nr_restarts = 0;
trans->nr_iters = 0;
trans->iters_live = 0;
trans->iters_linked = 0;
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
index e686a7ad5b3d..315cba28f6b2 100644
--- a/fs/bcachefs/btree_iter.h
+++ b/fs/bcachefs/btree_iter.h
@@ -305,10 +305,31 @@ bch2_trans_copy_iter(struct btree_trans *trans, struct btree_iter *src)
return __bch2_trans_copy_iter(trans, src, __btree_iter_id());
}
+void __bch2_trans_begin(struct btree_trans *);
+
void *bch2_trans_kmalloc(struct btree_trans *, size_t);
int bch2_trans_unlock(struct btree_trans *);
-void bch2_trans_begin(struct btree_trans *);
void bch2_trans_init(struct btree_trans *, struct bch_fs *);
int bch2_trans_exit(struct btree_trans *);
+#ifdef TRACE_TRANSACTION_RESTARTS
+#define bch2_trans_begin(_trans) \
+do { \
+ if (is_power_of_2((_trans)->nr_restarts) && \
+ (_trans)->nr_restarts >= 8) \
+ pr_info("nr restarts: %zu", (_trans)->nr_restarts); \
+ \
+ (_trans)->nr_restarts++; \
+ __bch2_trans_begin(_trans); \
+} while (0)
+#else
+#define bch2_trans_begin(_trans) __bch2_trans_begin(_trans)
+#endif
+
+#ifdef TRACE_TRANSACTION_RESTARTS_ALL
+#define trans_restart(...) pr_info("transaction restart" __VA_ARGS__)
+#else
+#define trans_restart(...) no_printk("transaction restart" __VA_ARGS__)
+#endif
+
#endif /* _BCACHEFS_BTREE_ITER_H */
diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h
index b922a8c104d4..438ef0c07623 100644
--- a/fs/bcachefs/btree_types.h
+++ b/fs/bcachefs/btree_types.h
@@ -269,6 +269,7 @@ struct btree_insert_entry {
struct btree_trans {
struct bch_fs *c;
+ size_t nr_restarts;
u8 nr_iters;
u8 iters_live;
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 4d1d0954efbf..6c48518e8c0b 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -333,6 +333,7 @@ static inline int do_btree_insert_at(struct btree_insert *trans,
if (race_fault()) {
ret = -EINTR;
+ trans_restart(" (race)");
goto out;
}
@@ -456,7 +457,12 @@ retry:
cycle_gc_lock = false;
trans_for_each_entry(trans, i) {
+ unsigned old_locks_want = i->iter->locks_want;
+ unsigned old_uptodate = i->iter->uptodate;
+
if (!bch2_btree_iter_upgrade(i->iter, 1, true)) {
+ trans_restart(" (failed upgrade, locks_want %u uptodate %u)",
+ old_locks_want, old_uptodate);
ret = -EINTR;
goto err;
}
@@ -529,8 +535,10 @@ err:
* don't care if we got ENOSPC because we told split it
* couldn't block:
*/
- if (!ret || (flags & BTREE_INSERT_NOUNLOCK))
+ if (!ret || (flags & BTREE_INSERT_NOUNLOCK)) {
+ trans_restart(" (split)");
ret = -EINTR;
+ }
}
if (cycle_gc_lock) {
@@ -545,13 +553,16 @@ err:
}
if (ret == -EINTR) {
- if (flags & BTREE_INSERT_NOUNLOCK)
+ if (flags & BTREE_INSERT_NOUNLOCK) {
+ trans_restart(" (can't unlock)");
goto out;
+ }
trans_for_each_entry(trans, i) {
int ret2 = bch2_btree_iter_traverse(i->iter);
if (ret2) {
ret = ret2;
+ trans_restart(" (traverse)");
goto out;
}
@@ -564,6 +575,8 @@ err:
*/
if (!(flags & BTREE_INSERT_ATOMIC))
goto retry;
+
+ trans_restart(" (atomic)");
}
goto out;