The 'ftdump' command in kdb is currently a bit of a last resort, at least if you have lots of traces turned on. It's going to print a whole boatload of lines out your serial port which is probably running at 115200. This could easily take many, many minutes.
Usually you're most interested in what's at the _end_ of the ftrace buffer, AKA what happened most recently. That means you've got to wait the full time for the dump. The 'ftdump' command does attempt to help you a little bit by allowing you to skip a fixed number of lines. Unfortunately it provides no way for you to know how many lines you should skip. Let's do similar to python and allow you to use a negative number to indicate that you want to skip all lines except the last few. This allows you to quickly see what you want. Signed-off-by: Douglas Anderson <diand...@chromium.org> --- Changes in v2: None kernel/trace/trace_kdb.c | 51 ++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c index 810d78a8d14c..7614b5c529f6 100644 --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c @@ -17,7 +17,7 @@ #include "trace.h" #include "trace_output.h" -static void ftrace_dump_buf(int skip_lines, long cpu_file) +static int ftrace_dump_buf(int skip_lines, long cpu_file, bool quiet) { /* use static because iter can be a bit big for the stack */ static struct trace_iterator iter; @@ -39,7 +39,9 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file) /* don't look at user memory in panic mode */ tr->trace_flags &= ~TRACE_ITER_SYM_USEROBJ; - kdb_printf("Dumping ftrace buffer:\n"); + if (!quiet) + kdb_printf("Dumping ftrace buffer (skipping %d lines):\n", + skip_lines); /* reset all but tr, trace, and overruns */ memset(&iter.seq, 0, @@ -66,25 +68,29 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file) } while (trace_find_next_entry_inc(&iter)) { - if (!cnt) - kdb_printf("---------------------------------\n"); - cnt++; - - if (!skip_lines) { - print_trace_line(&iter); - trace_printk_seq(&iter.seq); - } else { - skip_lines--; + if (!quiet) { + if (!cnt) + kdb_printf("---------------------------------\n"); + + if (!skip_lines) { + print_trace_line(&iter); + trace_printk_seq(&iter.seq); + } else { + skip_lines--; + } } + cnt++; if (KDB_FLAG(CMD_INTERRUPT)) goto out; } - if (!cnt) - kdb_printf(" (ftrace buffer empty)\n"); - else - kdb_printf("---------------------------------\n"); + if (!quiet) { + if (!cnt) + kdb_printf(" (ftrace buffer empty)\n"); + else + kdb_printf("---------------------------------\n"); + } out: tr->trace_flags = old_userobj; @@ -99,6 +105,8 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file) iter.buffer_iter[cpu] = NULL; } } + + return cnt; } /* @@ -109,6 +117,7 @@ static int kdb_ftdump(int argc, const char **argv) int skip_lines = 0; long cpu_file; char *cp; + int count; if (argc > 2) return KDB_ARGCOUNT; @@ -129,7 +138,14 @@ static int kdb_ftdump(int argc, const char **argv) } kdb_trap_printk++; - ftrace_dump_buf(skip_lines, cpu_file); + + /* A negative skip_lines means skip all but the last lines */ + if (skip_lines < 0) { + count = ftrace_dump_buf(0, cpu_file, true); + skip_lines = max(count + skip_lines, 0); + } + + count = ftrace_dump_buf(skip_lines, cpu_file, false); kdb_trap_printk--; return 0; @@ -138,7 +154,8 @@ static int kdb_ftdump(int argc, const char **argv) static __init int kdb_ftrace_register(void) { kdb_register_flags("ftdump", kdb_ftdump, "[skip_#lines] [cpu]", - "Dump ftrace log", 0, KDB_ENABLE_ALWAYS_SAFE); + "Dump ftrace log; -skip dumps last #lines", 0, + KDB_ENABLE_ALWAYS_SAFE); return 0; } -- 2.21.0.360.g471c308f928-goog