linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] tracing: kdb: Fix ftdump to not sleep
@ 2019-03-05 23:31 Douglas Anderson
  2019-03-05 23:31 ` [PATCH 2/2] tracing: kdb: Allow ftdump to skip all but the last few lines Douglas Anderson
  2019-03-05 23:47 ` [PATCH 1/2] tracing: kdb: Fix ftdump to not sleep Steven Rostedt
  0 siblings, 2 replies; 3+ messages in thread
From: Douglas Anderson @ 2019-03-05 23:31 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar, Jason Wessel, Daniel Thompson
  Cc: kgdb-bugreport, Brian Norris, Douglas Anderson, Vasyl Gomonovych,
	Tom Zanussi, linux-kernel, Baohong Liu, Masami Hiramatsu

As reported back in 2016-11 [1], the "ftdump" kdb command triggers a
BUG for "sleeping function called from invalid context".

kdb's "ftdump" command wants to call ring_buffer_read_prepare() in
atomic context.  A very simple solution for this is to just provide a
variant of ring_buffer_read_prepare that takes in allocation flags so
kdb can call it without triggering the allocation error.  This patch
does that.

Note that in the original email thread about this, it was suggested
that perhaps the solution for kdb was to either preallocate the buffer
ahead of time or create our own iterator.  I'm hoping that this
alternative of creating a variant of ring_buffer_read_prepare() can be
considered since it means I don't need to duplicate more of the core
trace code into "trace_kdb.c" (for either creating my own iterator or
re-preparing a ring allocator whose memory was already allocated).

NOTE: another option for kdb is to actually figure out how to make it
reuse the existing ftrace_dump() function and totally eliminate the
duplication.  This sounds very appealing and actually works (the "sr
z" command can be seen to properly dump the ftrace buffer).  The
downside here is that ftrace_dump() fully consumes the trace buffer.
Unless that is changed I'd rather not use it because it means "ftdump
| grep xyz" won't be very useful to search the ftrace buffer since it
will throw away the whole trace on the first grep.  A future patch to
dump only the last few lines of the buffer will also be hard to
implement.

[1] https://lkml.kernel.org/r/20161117191605.GA21459@google.com

Reported-by: Brian Norris <briannorris@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
---

 include/linux/ring_buffer.h |  2 ++
 kernel/trace/ring_buffer.c  | 42 +++++++++++++++++++++----------------
 kernel/trace/trace_kdb.c    |  6 ++++--
 3 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index 5b9ae62272bb..0c8ab8bf4cfb 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -127,6 +127,8 @@ struct ring_buffer_event *
 ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
 		    unsigned long *lost_events);
 
+struct ring_buffer_iter *
+_ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu, gfp_t flags);
 struct ring_buffer_iter *
 ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu);
 void ring_buffer_read_prepare_sync(void);
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 06e864a334bb..fd60007aa7a1 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -4201,6 +4201,29 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
 }
 EXPORT_SYMBOL_GPL(ring_buffer_consume);
 
+struct ring_buffer_iter *
+_ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu, gfp_t flags)
+{
+	struct ring_buffer_per_cpu *cpu_buffer;
+	struct ring_buffer_iter *iter;
+
+	if (!cpumask_test_cpu(cpu, buffer->cpumask))
+		return NULL;
+
+	iter = kmalloc(sizeof(*iter), flags);
+	if (!iter)
+		return NULL;
+
+	cpu_buffer = buffer->buffers[cpu];
+
+	iter->cpu_buffer = cpu_buffer;
+
+	atomic_inc(&buffer->resize_disabled);
+	atomic_inc(&cpu_buffer->record_disabled);
+
+	return iter;
+}
+
 /**
  * ring_buffer_read_prepare - Prepare for a non consuming read of the buffer
  * @buffer: The ring buffer to read from
@@ -4224,24 +4247,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_consume);
 struct ring_buffer_iter *
 ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu)
 {
-	struct ring_buffer_per_cpu *cpu_buffer;
-	struct ring_buffer_iter *iter;
-
-	if (!cpumask_test_cpu(cpu, buffer->cpumask))
-		return NULL;
-
-	iter = kmalloc(sizeof(*iter), GFP_KERNEL);
-	if (!iter)
-		return NULL;
-
-	cpu_buffer = buffer->buffers[cpu];
-
-	iter->cpu_buffer = cpu_buffer;
-
-	atomic_inc(&buffer->resize_disabled);
-	atomic_inc(&cpu_buffer->record_disabled);
-
-	return iter;
+	return _ring_buffer_read_prepare(buffer, cpu, GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(ring_buffer_read_prepare);
 
diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c
index d953c163a079..be84fa1ded35 100644
--- a/kernel/trace/trace_kdb.c
+++ b/kernel/trace/trace_kdb.c
@@ -51,14 +51,16 @@ static void ftrace_dump_buf(int skip_lines, long cpu_file)
 	if (cpu_file == RING_BUFFER_ALL_CPUS) {
 		for_each_tracing_cpu(cpu) {
 			iter.buffer_iter[cpu] =
-			ring_buffer_read_prepare(iter.trace_buffer->buffer, cpu);
+			_ring_buffer_read_prepare(iter.trace_buffer->buffer,
+						  cpu, GFP_ATOMIC);
 			ring_buffer_read_start(iter.buffer_iter[cpu]);
 			tracing_iter_reset(&iter, cpu);
 		}
 	} else {
 		iter.cpu_file = cpu_file;
 		iter.buffer_iter[cpu_file] =
-			ring_buffer_read_prepare(iter.trace_buffer->buffer, cpu_file);
+			_ring_buffer_read_prepare(iter.trace_buffer->buffer,
+						  cpu_file, GFP_ATOMIC);
 		ring_buffer_read_start(iter.buffer_iter[cpu_file]);
 		tracing_iter_reset(&iter, cpu_file);
 	}
-- 
2.21.0.352.gf09ad66450-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] tracing: kdb: Allow ftdump to skip all but the last few lines
  2019-03-05 23:31 [PATCH 1/2] tracing: kdb: Fix ftdump to not sleep Douglas Anderson
@ 2019-03-05 23:31 ` Douglas Anderson
  2019-03-05 23:47 ` [PATCH 1/2] tracing: kdb: Fix ftdump to not sleep Steven Rostedt
  1 sibling, 0 replies; 3+ messages in thread
From: Douglas Anderson @ 2019-03-05 23:31 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar, Jason Wessel, Daniel Thompson
  Cc: kgdb-bugreport, Brian Norris, Douglas Anderson, linux-kernel

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 <dianders@chromium.org>
---

 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 be84fa1ded35..40844e168a8c 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.352.gf09ad66450-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] tracing: kdb: Fix ftdump to not sleep
  2019-03-05 23:31 [PATCH 1/2] tracing: kdb: Fix ftdump to not sleep Douglas Anderson
  2019-03-05 23:31 ` [PATCH 2/2] tracing: kdb: Allow ftdump to skip all but the last few lines Douglas Anderson
@ 2019-03-05 23:47 ` Steven Rostedt
  1 sibling, 0 replies; 3+ messages in thread
From: Steven Rostedt @ 2019-03-05 23:47 UTC (permalink / raw)
  To: Douglas Anderson
  Cc: Ingo Molnar, Jason Wessel, Daniel Thompson, kgdb-bugreport,
	Brian Norris, Vasyl Gomonovych, Tom Zanussi, linux-kernel,
	Baohong Liu, Masami Hiramatsu

On Tue,  5 Mar 2019 15:31:49 -0800
Douglas Anderson <dianders@chromium.org> wrote:

> diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
> index 5b9ae62272bb..0c8ab8bf4cfb 100644
> --- a/include/linux/ring_buffer.h
> +++ b/include/linux/ring_buffer.h
> @@ -127,6 +127,8 @@ struct ring_buffer_event *
>  ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
>  		    unsigned long *lost_events);
>  
> +struct ring_buffer_iter *
> +_ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu, gfp_t flags);
>  struct ring_buffer_iter *
>  ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu);
>  void ring_buffer_read_prepare_sync(void);
> diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> index 06e864a334bb..fd60007aa7a1 100644
> --- a/kernel/trace/ring_buffer.c
> +++ b/kernel/trace/ring_buffer.c
> @@ -4201,6 +4201,29 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
>  }
>  EXPORT_SYMBOL_GPL(ring_buffer_consume);
>  
> +struct ring_buffer_iter *
> +_ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu, gfp_t flags)
> +{
> +	struct ring_buffer_per_cpu *cpu_buffer;

I don't care for this duplicate function. ring_buffer_read_prepare() is
only used in a few places, just add flags to it and to its users.

-- Steve

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-03-05 23:47 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-05 23:31 [PATCH 1/2] tracing: kdb: Fix ftdump to not sleep Douglas Anderson
2019-03-05 23:31 ` [PATCH 2/2] tracing: kdb: Allow ftdump to skip all but the last few lines Douglas Anderson
2019-03-05 23:47 ` [PATCH 1/2] tracing: kdb: Fix ftdump to not sleep Steven Rostedt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).