From 3ea4219d9894130008d723fb9e9c24290d4a42b6 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 12 Feb 2023 23:15:53 -0500 Subject: [PATCH] bcachefs: New backtrace utility code Signed-off-by: Kent Overstreet --- fs/bcachefs/btree_locking.c | 2 +- fs/bcachefs/debug.c | 2 +- fs/bcachefs/util.c | 44 +++++++++++++++++++++++++++++-------- fs/bcachefs/util.h | 8 ++++++- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/fs/bcachefs/btree_locking.c b/fs/bcachefs/btree_locking.c index cf138cd9d4319..49c7e94573c99 100644 --- a/fs/bcachefs/btree_locking.c +++ b/fs/bcachefs/btree_locking.c @@ -191,7 +191,7 @@ static noinline int break_cycle(struct lock_graph *g, struct printbuf *cycle) prt_printf(&buf, "backtrace:"); prt_newline(&buf); printbuf_indent_add(&buf, 2); - bch2_prt_backtrace(&buf, trans->locking_wait.task); + bch2_prt_task_backtrace(&buf, trans->locking_wait.task); printbuf_indent_sub(&buf, 2); prt_newline(&buf); } diff --git a/fs/bcachefs/debug.c b/fs/bcachefs/debug.c index fcefd55a53224..8f43581f3972d 100644 --- a/fs/bcachefs/debug.c +++ b/fs/bcachefs/debug.c @@ -527,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); - bch2_prt_backtrace(&i->buf, trans->locking_wait.task); + bch2_prt_task_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 e6672b67ae32a..12f4107662fcb 100644 --- a/fs/bcachefs/util.c +++ b/fs/bcachefs/util.c @@ -266,22 +266,48 @@ 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) +int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *task) { - unsigned long entries[32]; - unsigned i, nr_entries; + unsigned nr_entries = 0; + int ret = 0; + + stack->nr = 0; + ret = darray_make_room(stack, 32); + if (ret) + return ret; if (!down_read_trylock(&task->signal->exec_update_lock)) - return 0; + return -1; + + do { + nr_entries = stack_trace_save_tsk(task, stack->data, stack->size, 0); + } while (nr_entries == stack->size && + !(ret = darray_make_room(stack, stack->size * 2))); + + stack->nr = nr_entries; + up_read(&task->signal->exec_update_lock); - 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]); + return ret; +} + +void bch2_prt_backtrace(struct printbuf *out, bch_stacktrace *stack) +{ + unsigned long *i; + + darray_for_each(*stack, i) { + prt_printf(out, "[<0>] %pB", (void *) *i); prt_newline(out); } +} - up_read(&task->signal->exec_update_lock); - return 0; +int bch2_prt_task_backtrace(struct printbuf *out, struct task_struct *task) +{ + bch_stacktrace stack = { 0 }; + int ret = bch2_save_backtrace(&stack, task); + + bch2_prt_backtrace(out, &stack); + darray_exit(&stack); + return ret; } /* time stats: */ diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h index 67b0d3de24cc0..4188f380f54fd 100644 --- a/fs/bcachefs/util.h +++ b/fs/bcachefs/util.h @@ -20,6 +20,8 @@ #include "mean_and_variance.h" +#include "darray.h" + struct closure; #ifdef CONFIG_BCACHEFS_DEBUG @@ -361,7 +363,11 @@ 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 *); + +typedef DARRAY(unsigned long) bch_stacktrace; +int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *); +void bch2_prt_backtrace(struct printbuf *, bch_stacktrace *); +int bch2_prt_task_backtrace(struct printbuf *, struct task_struct *); #define NR_QUANTILES 15 #define QUANTILE_IDX(i) inorder_to_eytzinger0(i, NR_QUANTILES) -- 2.30.2