public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	"zhangwei(Jovi)" <jovi.zhangwei@huawei.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Steven Rostedt <rostedt@goodmis.org>
Subject: [ 24/26] tracing: Fix ftrace_dump()
Date: Thu,  9 May 2013 15:34:38 -0700	[thread overview]
Message-ID: <20130509223424.967355038@linuxfoundation.org> (raw)
In-Reply-To: <20130509223422.368544659@linuxfoundation.org>

3.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

commit 7fe70b579c9e3daba71635e31b6189394e7b79d3 upstream.

ftrace_dump() had a lot of issues. What ftrace_dump() does, is when
ftrace_dump_on_oops is set (via a kernel parameter or sysctl), it
will dump out the ftrace buffers to the console when either a oops,
panic, or a sysrq-z occurs.

This was written a long time ago when ftrace was fragile to recursion.
But it wasn't written well even for that.

There's a possible deadlock that can occur if a ftrace_dump() is happening
and an NMI triggers another dump. This is because it grabs a lock
before checking if the dump ran.

It also totally disables ftrace, and tracing for no good reasons.

As the ring_buffer now checks if it is read via a oops or NMI, where
there's a chance that the buffer gets corrupted, it will disable
itself. No need to have ftrace_dump() do the same.

ftrace_dump() is now cleaned up where it uses an atomic counter to
make sure only one dump happens at a time. A simple atomic_inc_return()
is enough that is needed for both other CPUs and NMIs. No need for
a spinlock, as if one CPU is running the dump, no other CPU needs
to do it too.

The tracing_on variable is turned off and not turned on. The original
code did this, but it wasn't pretty. By just disabling this variable
we get the result of not seeing traces that happen between crashes.

For sysrq-z, it doesn't get turned on, but the user can always write
a '1' to the tracing_on file. If they are using sysrq-z, then they should
know about tracing_on.

The new code is much easier to read and less error prone. No more
deadlock possibility when an NMI triggers here.

Reported-by: zhangwei(Jovi) <jovi.zhangwei@huawei.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 kernel/trace/trace.c          |   62 +++++++++++++++++-------------------------
 kernel/trace/trace_selftest.c |    9 +++---
 2 files changed, 31 insertions(+), 40 deletions(-)

--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4855,36 +4855,32 @@ void trace_init_global_iter(struct trace
 	iter->cpu_file = TRACE_PIPE_ALL_CPU;
 }
 
-static void
-__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode)
+void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
 {
-	static arch_spinlock_t ftrace_dump_lock =
-		(arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
 	/* use static because iter can be a bit big for the stack */
 	static struct trace_iterator iter;
+	static atomic_t dump_running;
 	unsigned int old_userobj;
-	static int dump_ran;
 	unsigned long flags;
 	int cnt = 0, cpu;
 
-	/* only one dump */
-	local_irq_save(flags);
-	arch_spin_lock(&ftrace_dump_lock);
-	if (dump_ran)
-		goto out;
-
-	dump_ran = 1;
+	/* Only allow one dump user at a time. */
+	if (atomic_inc_return(&dump_running) != 1) {
+		atomic_dec(&dump_running);
+		return;
+	}
 
+	/*
+	 * Always turn off tracing when we dump.
+	 * We don't need to show trace output of what happens
+	 * between multiple crashes.
+	 *
+	 * If the user does a sysrq-z, then they can re-enable
+	 * tracing with echo 1 > tracing_on.
+	 */
 	tracing_off();
 
-	/* Did function tracer already get disabled? */
-	if (ftrace_is_dead()) {
-		printk("# WARNING: FUNCTION TRACING IS CORRUPTED\n");
-		printk("#          MAY BE MISSING FUNCTION EVENTS\n");
-	}
-
-	if (disable_tracing)
-		ftrace_kill();
+	local_irq_save(flags);
 
 	trace_init_global_iter(&iter);
 
@@ -4917,6 +4913,12 @@ __ftrace_dump(bool disable_tracing, enum
 
 	printk(KERN_TRACE "Dumping ftrace buffer:\n");
 
+	/* Did function tracer already get disabled? */
+	if (ftrace_is_dead()) {
+		printk("# WARNING: FUNCTION TRACING IS CORRUPTED\n");
+		printk("#          MAY BE MISSING FUNCTION EVENTS\n");
+	}
+
 	/*
 	 * We need to stop all tracing on all CPUS to read the
 	 * the next buffer. This is a bit expensive, but is
@@ -4956,26 +4958,14 @@ __ftrace_dump(bool disable_tracing, enum
 		printk(KERN_TRACE "---------------------------------\n");
 
  out_enable:
-	/* Re-enable tracing if requested */
-	if (!disable_tracing) {
-		trace_flags |= old_userobj;
+	trace_flags |= old_userobj;
 
-		for_each_tracing_cpu(cpu) {
-			atomic_dec(&iter.tr->data[cpu]->disabled);
-		}
-		tracing_on();
+	for_each_tracing_cpu(cpu) {
+		atomic_dec(&iter.tr->data[cpu]->disabled);
 	}
-
- out:
-	arch_spin_unlock(&ftrace_dump_lock);
+ 	atomic_dec(&dump_running);
 	local_irq_restore(flags);
 }
-
-/* By default: disable tracing after the dump */
-void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
-{
-	__ftrace_dump(true, oops_dump_mode);
-}
 EXPORT_SYMBOL_GPL(ftrace_dump);
 
 __init static int tracer_alloc_buffers(void)
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -461,8 +461,6 @@ trace_selftest_startup_function(struct t
 /* Maximum number of functions to trace before diagnosing a hang */
 #define GRAPH_MAX_FUNC_TEST	100000000
 
-static void
-__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode);
 static unsigned int graph_hang_thresh;
 
 /* Wrap the real function entry probe to avoid possible hanging */
@@ -472,8 +470,11 @@ static int trace_graph_entry_watchdog(st
 	if (unlikely(++graph_hang_thresh > GRAPH_MAX_FUNC_TEST)) {
 		ftrace_graph_stop();
 		printk(KERN_WARNING "BUG: Function graph tracer hang!\n");
-		if (ftrace_dump_on_oops)
-			__ftrace_dump(false, DUMP_ALL);
+		if (ftrace_dump_on_oops) {
+			ftrace_dump(DUMP_ALL);
+			/* ftrace_dump() disables tracing */
+			tracing_on();
+		}
 		return 0;
 	}
 



  parent reply	other threads:[~2013-05-09 22:35 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-09 22:34 [ 00/26] 3.4.45-stable review Greg Kroah-Hartman
2013-05-09 22:34 ` [ 01/26] powerpc: Emulate non privileged DSCR read and write Greg Kroah-Hartman
2013-05-09 22:34 ` [ 02/26] powerpc: fix numa distance for form0 device tree Greg Kroah-Hartman
2013-05-09 22:34 ` [ 03/26] autofs - remove autofs dentry mount check Greg Kroah-Hartman
2013-05-09 22:34 ` [ 04/26] net/eth/ibmveth: Fixup retrieval of MAC address Greg Kroah-Hartman
2013-05-09 22:34 ` [ 05/26] perf/x86/intel/lbr: Fix LBR filter Greg Kroah-Hartman
2013-05-09 22:34 ` [ 06/26] perf/x86/intel/lbr: Demand proper privileges for PERF_SAMPLE_BRANCH_KERNEL Greg Kroah-Hartman
2013-05-09 22:34 ` [ 07/26] xhci: Dont warn on empty ring for suspended devices Greg Kroah-Hartman
2013-05-09 22:34 ` [ 08/26] ipvs: ip_vs_sip_fill_param() BUG: bad check of return value Greg Kroah-Hartman
2013-05-09 22:34 ` [ 09/26] ext4: add check for inodes_count overflow in new resize ioctl Greg Kroah-Hartman
2013-05-09 22:34 ` [ 10/26] r8169: fix 8168evl frame padding Greg Kroah-Hartman
2013-05-09 22:34 ` [ 11/26] cpufreq / Longhaul: Disable driver by default Greg Kroah-Hartman
2013-05-09 22:34 ` [ 12/26] drm/i915: Add no-lvds quirk for Fujitsu Esprimo Q900 Greg Kroah-Hartman
2013-05-09 22:34 ` [ 13/26] drm/i915: Fall back to bit banging mode for DVO transmitter detection Greg Kroah-Hartman
2013-05-09 22:34 ` [ 14/26] drm/radeon: dont use get_engine_clock() on APUs Greg Kroah-Hartman
2013-05-09 22:34 ` [ 15/26] drm/radeon/dce6: add missing display reg for tiling setup Greg Kroah-Hartman
2013-05-09 22:34 ` [ 16/26] drm/radeon: properly lock disp in mc_stop/resume for evergreen+ Greg Kroah-Hartman
2013-05-09 22:34 ` [ 17/26] drm/radeon: disable the crtcs in mc_stop (evergreen+) (v2) Greg Kroah-Hartman
2013-05-09 22:34 ` [ 18/26] drm/radeon: add some new SI PCI ids Greg Kroah-Hartman
2013-05-09 22:34 ` [ 19/26] drm/radeon/evergreen+: dont enable HPD interrupts on eDP/LVDS Greg Kroah-Hartman
2013-05-09 22:34 ` [ 20/26] drm/radeon: fix endian bugs in atom_allocate_fb_scratch() Greg Kroah-Hartman
2013-05-09 22:34 ` [ 21/26] drm/radeon: fix possible segfault when parsing pm tables Greg Kroah-Hartman
2013-05-09 22:34 ` [ 22/26] drm/radeon: add new richland pci ids Greg Kroah-Hartman
2013-05-09 22:34 ` [ 23/26] drm/radeon: fix handling of v6 power tables Greg Kroah-Hartman
2013-05-09 22:34 ` Greg Kroah-Hartman [this message]
2013-05-09 22:34 ` [ 25/26] kernel/audit_tree.c: tree will leak memory when failure occurs in audit_trim_trees() Greg Kroah-Hartman
2013-05-09 22:34 ` [ 26/26] x86/mm: account for PGDIR_SIZE alignment Greg Kroah-Hartman
2013-05-10 15:25 ` [ 00/26] 3.4.45-stable review Shuah Khan
2013-05-11  5:20 ` Satoru Takeuchi

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=20130509223424.967355038@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=fweisbec@gmail.com \
    --cc=jovi.zhangwei@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    /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