Commit cecbca96 authored by Frederic Weisbecker's avatar Frederic Weisbecker
Browse files

tracing: Dump either the oops's cpu source or all cpus buffers



The ftrace_dump_on_oops kernel parameter, sysctl and sysrq let one
dump every cpu buffers when an oops or panic happens.

It's nice when you have few cpus but it may take ages if have many,
plus you miss the real origin of the problem in all the cpu traces.

Sometimes, all you need is to dump the cpu buffer that triggered the
opps, most of the time it is our main interest.

This patch modifies ftrace_dump_on_oops to handle this choice.

The ftrace_dump_on_oops kernel parameter, when it comes alone, has
the same behaviour than before. But ftrace_dump_on_oops=orig_cpu
will only dump the buffer of the cpu that oops'ed.

Similarly, sysctl kernel.ftrace_dump_on_oops=1 and
echo 1 > /proc/sys/kernel/ftrace_dump_on_oops keep their previous
behaviour. But setting 2 jumps into cpu origin dump mode.

v2: Fix double setup
v3: Fix spelling issues reported by Randy Dunlap
v4: Also update __ftrace_dump in the selftests

Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Acked-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
parent b15c7b1c
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -789,8 +789,12 @@ and is between 256 and 4096 characters. It is defined in the file
			as early as possible in order to facilitate early
			boot debugging.

	ftrace_dump_on_oops
	ftrace_dump_on_oops[=orig_cpu]
			[FTRACE] will dump the trace buffers on oops.
			If no parameter is passed, ftrace will dump
			buffers of all CPUs, but if you pass orig_cpu, it will
			dump only the buffer of the CPU that triggered the
			oops.

	ftrace_filter=[function-list]
			[FTRACE] Limit the functions traced by the function
+4 −2
Original line number Diff line number Diff line
@@ -1337,12 +1337,14 @@ ftrace_dump_on_oops must be set. To set ftrace_dump_on_oops, one
can either use the sysctl function or set it via the proc system
interface.

  sysctl kernel.ftrace_dump_on_oops=1
  sysctl kernel.ftrace_dump_on_oops=n

or

  echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
  echo n > /proc/sys/kernel/ftrace_dump_on_oops

If n = 1, ftrace will dump buffers of all CPUs, if n = 2 ftrace will
only dump the buffer of the CPU that triggered the oops.

Here's an example of such a dump after a null pointer
dereference in a kernel module:
+1 −1
Original line number Diff line number Diff line
@@ -289,7 +289,7 @@ static struct sysrq_key_op sysrq_showstate_blocked_op = {

static void sysrq_ftrace_dump(int key, struct tty_struct *tty)
{
	ftrace_dump();
	ftrace_dump(DUMP_ALL);
}
static struct sysrq_key_op sysrq_ftrace_dump_op = {
	.handler	= sysrq_ftrace_dump,
+3 −1
Original line number Diff line number Diff line
@@ -492,7 +492,9 @@ static inline int test_tsk_trace_graph(struct task_struct *tsk)
	return tsk->trace & TSK_TRACE_FL_GRAPH;
}

extern int ftrace_dump_on_oops;
enum ftrace_dump_mode;

extern enum ftrace_dump_mode ftrace_dump_on_oops;

#ifdef CONFIG_PREEMPT
#define INIT_TRACE_RECURSION		.trace_recursion = 0,
+9 −2
Original line number Diff line number Diff line
@@ -490,6 +490,13 @@ static inline void tracing_off(void) { }
static inline void tracing_off_permanent(void) { }
static inline int tracing_is_on(void) { return 0; }
#endif

enum ftrace_dump_mode {
	DUMP_NONE,
	DUMP_ALL,
	DUMP_ORIG,
};

#ifdef CONFIG_TRACING
extern void tracing_start(void);
extern void tracing_stop(void);
@@ -571,7 +578,7 @@ __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
extern int
__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);

extern void ftrace_dump(void);
extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
#else
static inline void
ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
@@ -592,7 +599,7 @@ ftrace_vprintk(const char *fmt, va_list ap)
{
	return 0;
}
static inline void ftrace_dump(void) { }
static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
#endif /* CONFIG_TRACING */

/*
Loading