summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/btree_locking.c24
-rw-r--r--fs/bcachefs/debug.c22
-rw-r--r--fs/bcachefs/util.c20
-rw-r--r--fs/bcachefs/util.h1
4 files changed, 45 insertions, 22 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)
diff --git a/fs/bcachefs/debug.c b/fs/bcachefs/debug.c
index c7d558381388..7abc707d2f38 100644
--- a/fs/bcachefs/debug.c
+++ b/fs/bcachefs/debug.c
@@ -501,26 +501,6 @@ static const struct file_operations cached_btree_nodes_ops = {
};
#ifdef CONFIG_BCACHEFS_DEBUG_TRANSACTIONS
-static int prt_backtrace(struct printbuf *out, struct task_struct *task)
-{
- unsigned long entries[32];
- unsigned i, nr_entries;
- int ret;
-
- ret = down_read_killable(&task->signal->exec_update_lock);
- if (ret)
- return ret;
-
- nr_entries = stack_trace_save_tsk(task, entries, ARRAY_SIZE(entries), 0);
- for (i = 0; i < nr_entries; i++) {
- prt_printf(out, "[<0>] %pB", (void *)entries[i]);
- prt_newline(out);
- }
-
- up_read(&task->signal->exec_update_lock);
- return 0;
-}
-
static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf,
size_t size, loff_t *ppos)
{
@@ -547,7 +527,7 @@ static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf,
prt_printf(&i->buf, "backtrace:");
prt_newline(&i->buf);
printbuf_indent_add(&i->buf, 2);
- prt_backtrace(&i->buf, trans->locking_wait.task);
+ bch2_prt_backtrace(&i->buf, trans->locking_wait.task);
printbuf_indent_sub(&i->buf, 2);
prt_newline(&i->buf);
diff --git a/fs/bcachefs/util.c b/fs/bcachefs/util.c
index 477c260de50b..bf529bb137ed 100644
--- a/fs/bcachefs/util.c
+++ b/fs/bcachefs/util.c
@@ -265,6 +265,26 @@ void bch2_print_string_as_lines(const char *prefix, const char *lines)
console_unlock();
}
+int bch2_prt_backtrace(struct printbuf *out, struct task_struct *task)
+{
+ unsigned long entries[32];
+ unsigned i, nr_entries;
+ int ret;
+
+ ret = down_read_killable(&task->signal->exec_update_lock);
+ if (ret)
+ return ret;
+
+ nr_entries = stack_trace_save_tsk(task, entries, ARRAY_SIZE(entries), 0);
+ for (i = 0; i < nr_entries; i++) {
+ prt_printf(out, "[<0>] %pB", (void *)entries[i]);
+ prt_newline(out);
+ }
+
+ up_read(&task->signal->exec_update_lock);
+ return 0;
+}
+
/* time stats: */
#ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT
diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h
index a16f8bb9d415..3b0090faef4d 100644
--- a/fs/bcachefs/util.h
+++ b/fs/bcachefs/util.h
@@ -383,6 +383,7 @@ u64 bch2_read_flag_list(char *, const char * const[]);
void bch2_prt_u64_binary(struct printbuf *, u64, unsigned);
void bch2_print_string_as_lines(const char *prefix, const char *lines);
+int bch2_prt_backtrace(struct printbuf *, struct task_struct *);
#define NR_QUANTILES 15
#define QUANTILE_IDX(i) inorder_to_eytzinger0(i, NR_QUANTILES)