summaryrefslogtreecommitdiff
path: root/fs/bcachefs/btree_locking.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-10-09 11:29:04 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:42 +0300
commit1148a97f1fb9b80ef5355021f0c2dfc7b8f003a2 (patch)
tree6acb14dfff4d86d895e01b67aca7428b6abb7723 /fs/bcachefs/btree_locking.c
parent1be887979bc12a6c88b33b0d53dfdc369bfa9d49 (diff)
downloadlinux-1148a97f1fb9b80ef5355021f0c2dfc7b8f003a2.tar.xz
bcachefs: Print cycle on unrecoverable deadlock
Some lock operations can't fail; a cycle of nofail locks is impossible to recover from. So we want to get rid of these nofail locking operations, but as this is tricky it'll be done incrementally. If such a cycle happens, this patch prints out which codepaths are involved so we know what to work on next. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_locking.c')
-rw-r--r--fs/bcachefs/btree_locking.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/fs/bcachefs/btree_locking.c b/fs/bcachefs/btree_locking.c
index ad6e364980f3..3973e8d7e6da 100644
--- a/fs/bcachefs/btree_locking.c
+++ b/fs/bcachefs/btree_locking.c
@@ -138,7 +138,29 @@ static noinline int break_cycle(struct lock_graph *g)
return abort_lock(g, i);
}
- BUG();
+ {
+ struct bch_fs *c = g->g->trans->c;
+ struct printbuf buf = PRINTBUF;
+
+ bch_err(c, "cycle of nofail locks");
+
+ for (i = g->g; i < g->g + g->nr; i++) {
+ struct btree_trans *trans = i->trans;
+
+ bch2_btree_trans_to_text(&buf, trans);
+
+ prt_printf(&buf, "backtrace:");
+ prt_newline(&buf);
+ printbuf_indent_add(&buf, 2);
+ bch2_prt_backtrace(&buf, trans->locking_wait.task);
+ printbuf_indent_sub(&buf, 2);
+ prt_newline(&buf);
+ }
+
+ bch2_print_string_as_lines(KERN_ERR, buf.buf);
+ printbuf_exit(&buf);
+ BUG();
+ }
}
static void lock_graph_pop(struct lock_graph *g)