mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Jason Wessel <jason.wessel@windriver.com>
Cc: linux-kernel@vger.kernel.org,
	kgdb-bugreport@lists.sourceforge.net, mingo@elte.hu
Subject: Re: [PATCH 40/40] ftrace,kdb: Extend kdb to be able to dump the ftrace buffer
Date: Thu, 14 Jan 2010 19:14:26 -0500	[thread overview]
Message-ID: <1263514466.28171.3965.camel@gandalf.stny.rr.com> (raw)
In-Reply-To: <1263481176-1897-41-git-send-email-jason.wessel@windriver.com>

On Thu, 2010-01-14 at 08:59 -0600, Jason Wessel wrote:
> Add in a helper function to allow the kdb shell to dump the ftrace
> buffer.
> 

Acked-by: Steven Rostedt <rostedt@goodmis.org>


If this is the final version, I could queue it up in my tree for 34, and
push it off to Ingo.

-- Steve

> Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
> ---
>  Documentation/DocBook/kgdb.tmpl |    3 +-
>  kernel/trace/Makefile           |    3 +
>  kernel/trace/trace.c            |   48 +++++++---------
>  kernel/trace/trace.h            |   17 ++++++
>  kernel/trace/trace_kdb.c        |  116 +++++++++++++++++++++++++++++++++++++++
>  5 files changed, 160 insertions(+), 27 deletions(-)
>  create mode 100644 kernel/trace/trace_kdb.c
> 
> diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl
> index bbf4a22..b01b5b1 100644
> --- a/Documentation/DocBook/kgdb.tmpl
> +++ b/Documentation/DocBook/kgdb.tmpl
> @@ -675,7 +675,8 @@ Task Addr       Pid   Parent [*] cpu State Thread     Command
>        <itemizedlist>
>          <listitem><para>A simple shell</para></listitem>
>          <listitem><para>The kdb core command set</para></listitem>
> -        <listitem><para>A registration API to register additional kdb shell commands.</para></listitem>
> +        <listitem><para>A registration API to register additional kdb shell commands.</para>
> +        <para>A good example of a self contained kdb module is the "ftdump" command for dumping the ftrace buffer.  See: kernel/trace/trace_kdb.c</para></listitem>
>          <listitem><para>The implementation for kdb_printf() which emit messages directly to I/O drivers, bypassing the kernel log.</para></listitem>
>          <listitem><para>SW / HW breakpoint management for the kdb shell</para></listitem>
>        </itemizedlist>
> diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
> index cd9ecd8..c48a28f 100644
> --- a/kernel/trace/Makefile
> +++ b/kernel/trace/Makefile
> @@ -56,5 +56,8 @@ obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
>  obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o
>  obj-$(CONFIG_KSYM_TRACER) += trace_ksym.o
>  obj-$(CONFIG_EVENT_TRACING) += power-traces.o
> +ifeq ($(CONFIG_TRACING),y)
> +obj-$(CONFIG_KGDB_KDB) += trace_kdb.o
> +endif
>  
>  libftrace-y := ftrace.o
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 0df1b0f..b3c786a 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -100,14 +100,11 @@ static inline void ftrace_enable_cpu(void)
>  	preempt_enable();
>  }
>  
> -static cpumask_var_t __read_mostly	tracing_buffer_mask;
> +cpumask_var_t __read_mostly	tracing_buffer_mask;
>  
>  /* Define which cpu buffers are currently read in trace_pipe */
>  static cpumask_var_t			tracing_reader_cpumask;
>  
> -#define for_each_tracing_cpu(cpu)	\
> -	for_each_cpu(cpu, tracing_buffer_mask)
> -
>  /*
>   * ftrace_dump_on_oops - variable to dump ftrace buffer on oops
>   *
> @@ -1409,11 +1406,6 @@ int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
>  }
>  EXPORT_SYMBOL_GPL(trace_vprintk);
>  
> -enum trace_file_type {
> -	TRACE_FILE_LAT_FMT	= 1,
> -	TRACE_FILE_ANNOTATE	= 2,
> -};
> -
>  static void trace_iterator_increment(struct trace_iterator *iter)
>  {
>  	/* Don't allow ftrace to trace into the ring buffers */
> @@ -1503,7 +1495,7 @@ struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
>  }
>  
>  /* Find the next real entry, and increment the iterator to the next entry */
> -static void *find_next_entry_inc(struct trace_iterator *iter)
> +void *trace_find_next_entry_inc(struct trace_iterator *iter)
>  {
>  	iter->ent = __find_next_entry(iter, &iter->cpu, &iter->ts);
>  
> @@ -1536,12 +1528,12 @@ static void *s_next(struct seq_file *m, void *v, loff_t *pos)
>  		return NULL;
>  
>  	if (iter->idx < 0)
> -		ent = find_next_entry_inc(iter);
> +		ent = trace_find_next_entry_inc(iter);
>  	else
>  		ent = iter;
>  
>  	while (ent && iter->idx < i)
> -		ent = find_next_entry_inc(iter);
> +		ent = trace_find_next_entry_inc(iter);
>  
>  	iter->pos = *pos;
>  
> @@ -1878,7 +1870,7 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
>  	return event ? event->binary(iter, 0) : TRACE_TYPE_HANDLED;
>  }
>  
> -static int trace_empty(struct trace_iterator *iter)
> +int trace_empty(struct trace_iterator *iter)
>  {
>  	int cpu;
>  
> @@ -1909,7 +1901,7 @@ static int trace_empty(struct trace_iterator *iter)
>  }
>  
>  /*  Called with trace_event_read_lock() held. */
> -static enum print_line_t print_trace_line(struct trace_iterator *iter)
> +enum print_line_t print_trace_line(struct trace_iterator *iter)
>  {
>  	enum print_line_t ret;
>  
> @@ -3074,7 +3066,7 @@ waitagain:
>  	iter->pos = -1;
>  
>  	trace_event_read_lock();
> -	while (find_next_entry_inc(iter) != NULL) {
> +	while (trace_find_next_entry_inc(iter) != NULL) {
>  		enum print_line_t ret;
>  		int len = iter->seq.len;
>  
> @@ -3156,7 +3148,7 @@ tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter)
>  		if (ret != TRACE_TYPE_NO_CONSUME)
>  			trace_consume(iter);
>  		rem -= count;
> -		if (!find_next_entry_inc(iter))	{
> +		if (!trace_find_next_entry_inc(iter))	{
>  			rem = 0;
>  			iter->ent = NULL;
>  			break;
> @@ -3209,7 +3201,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
>  	if (ret <= 0)
>  		goto out_err;
>  
> -	if (!iter->ent && !find_next_entry_inc(iter)) {
> +	if (!iter->ent && !trace_find_next_entry_inc(iter)) {
>  		ret = -EFAULT;
>  		goto out_err;
>  	}
> @@ -4262,7 +4254,7 @@ static struct notifier_block trace_die_notifier = {
>   */
>  #define KERN_TRACE		KERN_EMERG
>  
> -static void
> +void
>  trace_printk_seq(struct trace_seq *s)
>  {
>  	/* Probably should print a warning here. */
> @@ -4277,6 +4269,13 @@ trace_printk_seq(struct trace_seq *s)
>  	trace_seq_init(s);
>  }
>  
> +void trace_init_global_iter(struct trace_iterator *iter)
> +{
> +	iter->tr = &global_trace;
> +	iter->trace = current_trace;
> +	iter->cpu_file = TRACE_PIPE_ALL_CPU;
> +}
> +
>  static void __ftrace_dump(bool disable_tracing)
>  {
>  	static arch_spinlock_t ftrace_dump_lock =
> @@ -4301,8 +4300,10 @@ static void __ftrace_dump(bool disable_tracing)
>  	if (disable_tracing)
>  		ftrace_kill();
>  
> +	trace_init_global_iter(&iter);
> +
>  	for_each_tracing_cpu(cpu) {
> -		atomic_inc(&global_trace.data[cpu]->disabled);
> +		atomic_inc(&iter.tr->data[cpu]->disabled);
>  	}
>  
>  	old_userobj = trace_flags & TRACE_ITER_SYM_USEROBJ;
> @@ -4312,11 +4313,6 @@ static void __ftrace_dump(bool disable_tracing)
>  
>  	printk(KERN_TRACE "Dumping ftrace buffer:\n");
>  
> -	/* Simulate the iterator */
> -	iter.tr = &global_trace;
> -	iter.trace = current_trace;
> -	iter.cpu_file = TRACE_PIPE_ALL_CPU;
> -
>  	/*
>  	 * We need to stop all tracing on all CPUS to read the
>  	 * the next buffer. This is a bit expensive, but is
> @@ -4338,7 +4334,7 @@ static void __ftrace_dump(bool disable_tracing)
>  		iter.iter_flags |= TRACE_FILE_LAT_FMT;
>  		iter.pos = -1;
>  
> -		if (find_next_entry_inc(&iter) != NULL) {
> +		if (trace_find_next_entry_inc(&iter) != NULL) {
>  			int ret;
>  
>  			ret = print_trace_line(&iter);
> @@ -4359,7 +4355,7 @@ static void __ftrace_dump(bool disable_tracing)
>  		trace_flags |= old_userobj;
>  
>  		for_each_tracing_cpu(cpu) {
> -			atomic_dec(&global_trace.data[cpu]->disabled);
> +			atomic_dec(&iter.tr->data[cpu]->disabled);
>  		}
>  		tracing_on();
>  	}
> diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
> index 4df6a77..563e6f8 100644
> --- a/kernel/trace/trace.h
> +++ b/kernel/trace/trace.h
> @@ -352,6 +352,12 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
>  struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
>  					  int *ent_cpu, u64 *ent_ts);
>  
> +int trace_empty(struct trace_iterator *iter);
> +
> +void *trace_find_next_entry_inc(struct trace_iterator *iter);
> +
> +void trace_init_global_iter(struct trace_iterator *iter);
> +
>  void default_wait_pipe(struct trace_iterator *iter);
>  void poll_wait_pipe(struct trace_iterator *iter);
>  
> @@ -391,6 +397,15 @@ void tracing_start_sched_switch_record(void);
>  int register_tracer(struct tracer *type);
>  void unregister_tracer(struct tracer *type);
>  int is_tracing_stopped(void);
> +enum trace_file_type {
> +	TRACE_FILE_LAT_FMT	= 1,
> +	TRACE_FILE_ANNOTATE	= 2,
> +};
> +
> +extern cpumask_var_t __read_mostly tracing_buffer_mask;
> +
> +#define for_each_tracing_cpu(cpu)	\
> +	for_each_cpu(cpu, tracing_buffer_mask)
>  
>  extern int process_new_ksym_entry(char *ksymname, int op, unsigned long addr);
>  
> @@ -483,6 +498,8 @@ trace_array_vprintk(struct trace_array *tr,
>  		    unsigned long ip, const char *fmt, va_list args);
>  int trace_array_printk(struct trace_array *tr,
>  		       unsigned long ip, const char *fmt, ...);
> +void trace_printk_seq(struct trace_seq *s);
> +enum print_line_t print_trace_line(struct trace_iterator *iter);
>  
>  extern unsigned long trace_flags;
>  
> diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c
> new file mode 100644
> index 0000000..9227ff3
> --- /dev/null
> +++ b/kernel/trace/trace_kdb.c
> @@ -0,0 +1,116 @@
> +/*
> + * kdb helper for dumping the ftrace buffer
> + *
> + * Copyright (C) 2010 Jason Wessel <jason.wessel@windriver.com>
> + *
> + * ftrace_dump_buf based on ftrace_dump:
> + * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
> + * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
> + *
> + */
> +#include <linux/init.h>
> +#include <linux/kgdb.h>
> +#include <linux/kdb.h>
> +#include <linux/ftrace.h>
> +
> +#include "../debug/kdb/kdb_private.h"
> +#include "trace.h"
> +#include "trace_output.h"
> +
> +static void ftrace_dump_buf(int skip_lines)
> +{
> +	/* use static because iter can be a bit big for the stack */
> +	static struct trace_iterator iter;
> +	unsigned int old_userobj;
> +	int cnt = 0, cpu;
> +
> +	trace_init_global_iter(&iter);
> +
> +	for_each_tracing_cpu(cpu) {
> +		atomic_inc(&iter.tr->data[cpu]->disabled);
> +	}
> +
> +	old_userobj = trace_flags;
> +
> +	/* don't look at user memory in panic mode */
> +	trace_flags &= ~TRACE_ITER_SYM_USEROBJ;
> +
> +	kdb_printf("Dumping ftrace buffer:\n");
> +
> +	/* reset all but tr, trace, and overruns */
> +	memset(&iter.seq, 0,
> +		   sizeof(struct trace_iterator) -
> +		   offsetof(struct trace_iterator, seq));
> +	iter.iter_flags |= TRACE_FILE_LAT_FMT;
> +	iter.pos = -1;
> +
> +	for_each_tracing_cpu(cpu)
> +		iter.buffer_iter[cpu] =
> +			ring_buffer_read_start(iter.tr->buffer, cpu);
> +
> +	if (!trace_empty(&iter))
> +		trace_find_next_entry_inc(&iter);
> +	while (!trace_empty(&iter)) {
> +		if (!cnt)
> +			kdb_printf("---------------------------------\n");
> +		cnt++;
> +
> +		if (trace_find_next_entry_inc(&iter) != NULL && !skip_lines)
> +			print_trace_line(&iter);
> +		if (!skip_lines)
> +			trace_printk_seq(&iter.seq);
> +		else
> +			skip_lines--;
> +		if (KDB_FLAG(CMD_INTERRUPT))
> +			goto out;
> +	}
> +
> +	if (!cnt)
> +		kdb_printf("   (ftrace buffer empty)\n");
> +	else
> +		kdb_printf("---------------------------------\n");
> +
> +out:
> +	trace_flags = old_userobj;
> +
> +	for_each_tracing_cpu(cpu) {
> +		atomic_dec(&iter.tr->data[cpu]->disabled);
> +	}
> +
> +	for_each_tracing_cpu(cpu)
> +		if (iter.buffer_iter[cpu])
> +			ring_buffer_read_finish(iter.buffer_iter[cpu]);
> +}
> +
> +/*
> + * kdb_ftdump - Dump the ftrace log buffer
> + */
> +static int kdb_ftdump(int argc, const char **argv)
> +{
> +	int skip_lines = 0;
> +	char *cp;
> +
> +	if (argc > 1)
> +		return KDB_ARGCOUNT;
> +
> +	if (argc) {
> +		skip_lines = simple_strtol(argv[1], &cp, 0);
> +		if (*cp)
> +			skip_lines = 0;
> +	}
> +
> +	kdb_trap_printk++;
> +	ftrace_dump_buf(skip_lines);
> +	kdb_trap_printk--;
> +
> +	return 0;
> +}
> +
> +static __init int kdb_ftrace_register(void)
> +{
> +	kdb_register_repeat("ftdump", kdb_ftdump, "", "Dump ftrace log",
> +			    0, KDB_REPEAT_NONE);
> +	return 0;
> +}
> +
> +late_initcall(kdb_ftrace_register);



  reply	other threads:[~2010-01-15  0:14 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-14 14:58 [PATCH 0/40] kgdb, kdb and atomic kernel modesetting series Jason Wessel
2010-01-14 14:58 ` [PATCH 01/40] softlockup: add sched_clock_tick() to avoid kernel warning on kgdb resume Jason Wessel
2010-01-14 14:58 ` [PATCH 02/40] x86,hw_breakpoint,kgdb: kgdb to use hw_breakpoint API Jason Wessel
2010-01-14 14:58 ` [PATCH 03/40] Move kernel/kgdb.c to kernel/debug/debug_core.c Jason Wessel
2010-01-14 14:59 ` [PATCH 04/40] Separate the gdbstub from the debug core Jason Wessel
2010-01-14 14:59 ` [PATCH 05/40] kgdb: eliminate kgdb_wait(), all cpus enter the same way Jason Wessel
2010-01-14 14:59 ` [PATCH 06/40] kgdb,sparc: Add in kgdb_arch_set_pc for sparc Jason Wessel
2010-01-14 14:59 ` [PATCH 07/40] kgdb,sh: update superh kgdb exception handling Jason Wessel
2010-01-14 14:59 ` [PATCH 08/40] kgdb,blackfin: Add in kgdb_arch_set_pc for blackfin Jason Wessel
2010-01-14 14:59 ` [PATCH 09/40] kdb: core for kgdb back end (1 of 2) Jason Wessel
2010-01-14 14:59 ` [PATCH 10/40] kdb: core for kgdb back end (2 " Jason Wessel
2010-01-14 14:59 ` [PATCH 11/40] kgdb: core changes to support kdb Jason Wessel
2010-01-14 14:59 ` [PATCH 12/40] kgdb,8250,pl011: Return immediately from console poll Jason Wessel
2010-01-14 14:59 ` [PATCH 13/40] sh,sh-sci: Use NO_POLL_CHAR in the SCIF polled console code Jason Wessel
2010-01-14 14:59 ` [PATCH 14/40] sparc,sunzilog: Add console polling support for sunzilog serial driver Jason Wessel
2010-01-14 14:59 ` [PATCH 15/40] kgdb: gdb "monitor" -> kdb passthrough Jason Wessel
2010-01-14 14:59 ` [PATCH 16/40] kgdboc,keyboard: Keyboard driver for kdb with kgdb Jason Wessel
2010-01-14 14:59 ` [PATCH 17/40] kgdb,docs: Update the kgdb docs to include kdb Jason Wessel
2010-01-14 14:59 ` [PATCH 18/40] kgdb: remove post_primary_code references Jason Wessel
2010-01-14 14:59 ` [PATCH 19/40] x86,kgdb: Add low level debug hook Jason Wessel
2010-01-14 14:59 ` [PATCH 20/40] arm,kgdb: Add hook to catch an oops with debugger Jason Wessel
2010-01-14 17:48   ` Russell King - ARM Linux
2010-01-14 18:57     ` Jason Wessel
2010-01-14 20:29     ` Jason Wessel
2010-01-14 20:46       ` Russell King - ARM Linux
2010-01-18 14:30         ` Jason Wessel
2010-01-20 16:03           ` Russell King - ARM Linux
2010-01-20 17:01             ` Jason Wessel
2010-01-14 14:59 ` [PATCH 21/40] powerpc,kgdb: Introduce low level trap catching Jason Wessel
2010-01-14 14:59 ` [PATCH 22/40] mips,kgdb: kdb low level trap catch and stack trace Jason Wessel
2010-01-14 17:29   ` David Daney
2010-01-14 22:32     ` Jason Wessel
2010-01-14 14:59 ` [PATCH 23/40] kgdb: Add the ability to schedule a breakpoint via a tasklet Jason Wessel
2010-01-14 14:59 ` [PATCH 24/40] kgdboc,kdb: Allow kdb to work on a non open console port Jason Wessel
2010-01-14 14:59 ` [PATCH 25/40] printk,kdb: capture printk() when in kdb shell Jason Wessel
2010-01-14 14:59 ` [PATCH 26/40] keyboard, input: Add hook to input to allow low level event clear Jason Wessel
2010-01-14 14:59 ` [PATCH 27/40] debug_core,kdb: Allow the debug core to process a recursive debug entry Jason Wessel
2010-01-14 14:59 ` [PATCH 28/40] kdb,panic,debug_core: Allow the debug core to receive a panic before smp_send_stop() Jason Wessel
2010-01-14 14:59 ` [PATCH 29/40] MAINTAINERS: update kgdb, kdb, and debug_core info Jason Wessel
2010-01-14 14:59 ` [PATCH 30/40] kgdboc,debug_core: Add call backs to allow kernel mode switching Jason Wessel
2010-01-14 14:59 ` [PATCH 31/40] kgdb: add ops arg to kgdb console active & restore hooks Jason Wessel
2010-01-14 14:59 ` [PATCH 32/40] drm: add KGDB/KDB support Add support for KDB entry/exit Jason Wessel
2010-01-14 14:59 ` [PATCH 33/40] kms,kdb: Force unblank a console device Jason Wessel
2010-01-14 14:59 ` [PATCH 34/40] i915: when kgdb is active display compression should be off Jason Wessel
2010-01-14 14:59 ` [PATCH 35/40] drm_fb_helper: Preserve capability to use atomic kms Jason Wessel
2010-01-14 14:59 ` [PATCH 36/40] drm,i915 - atomic mutex hacks Jason Wessel
2010-01-14 14:59 ` [PATCH 37/40] kgdb,docs: Update the kgdb docs to include kms Jason Wessel
2010-01-14 14:59 ` [PATCH 38/40] kgdbts,sh: Add in breakpoint pc offset for superh Jason Wessel
2010-01-14 14:59 ` [PATCH 39/40] debug_core: Turn off tracing while in the debugger Jason Wessel
2010-01-15  0:10   ` Steven Rostedt
2010-01-15 14:03     ` Jason Wessel
2010-01-15 15:04       ` Steven Rostedt
2010-01-14 14:59 ` [PATCH 40/40] ftrace,kdb: Extend kdb to be able to dump the ftrace buffer Jason Wessel
2010-01-15  0:14   ` Steven Rostedt [this message]
2010-01-15 13:15     ` Jason Wessel
2010-01-30  2:02 ` [PATCH 0/40] kgdb, kdb and atomic kernel modesetting series Jon Masters

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1263514466.28171.3965.camel@gandalf.stny.rr.com \
    --to=rostedt@goodmis.org \
    --cc=jason.wessel@windriver.com \
    --cc=kgdb-bugreport@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®