diff options
-rw-r--r-- | fs/bcachefs/btree_locking.c | 24 | ||||
-rw-r--r-- | fs/bcachefs/debug.c | 22 | ||||
-rw-r--r-- | fs/bcachefs/util.c | 20 | ||||
-rw-r--r-- | fs/bcachefs/util.h | 1 |
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) |