public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Ingo Molnar <mingo@elte.hu>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Christoph Hellwig <hch@infradead.org>,
	Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>,
	Gregory Haskins <ghaskins@novell.com>,
	Arnaldo Carvalho de Melo <acme@ghostprotocols.net>,
	Thomas Gleixner <tglx@linutronix.de>,
	Tim Bird <tim.bird@am.sony.com>, Sam Ravnborg <sam@ravnborg.org>,
	"Frank Ch. Eigler" <fche@redhat.com>,
	Jan Kiszka <jan.kiszka@siemens.com>,
	Steven Rostedt <srostedt@redhat.com>
Subject: [RFC PATCH 08/30 v3] mcount tracer output file
Date: Tue, 15 Jan 2008 15:49:15 -0500	[thread overview]
Message-ID: <20080115205022.585424916@goodmis.org> (raw)
In-Reply-To: 20080115204907.838227723@goodmis.org

[-- Attachment #1: mcount-tracer-debugfs-show.patch --]
[-- Type: text/plain, Size: 7564 bytes --]

Add /debugfs/tracing/trace to output trace output.

Here's an example of the content.

  CPU 0:  [<ffffffff80494691>] notifier_call_chain+0x16/0x60 <-- [<ffffffff80494701>] __atomic_notifier_call_chain+0x26/0x56
  CPU 0:  [<ffffffff802161c8>] mce_idle_callback+0x9/0x2f <-- [<ffffffff804946b3>] notifier_call_chain+0x38/0x60
  CPU 0:  [<ffffffff8037fb7a>] acpi_processor_idle+0x16/0x518 <-- [<ffffffff8020aee8>] cpu_idle+0xa1/0xe7
  CPU 0:  [<ffffffff8037fa98>] acpi_safe_halt+0x9/0x43 <-- [<ffffffff8037fd3a>] acpi_processor_idle+0x1d6/0x518
  CPU 1:  [<ffffffff80221db8>] smp_apic_timer_interrupt+0xc/0x58 <-- [<ffffffff8020cf06>] apic_timer_interrupt+0x66/0x70
  CPU 1:  [<ffffffff8020ac22>] exit_idle+0x9/0x22 <-- [<ffffffff80221de1>] smp_apic_timer_interrupt+0x35/0x58
  CPU 1:  [<ffffffff8020ab97>] __exit_idle+0x9/0x2e <-- [<ffffffff8020ac39>] exit_idle+0x20/0x22
  CPU 1:  [<ffffffff8049473a>] atomic_notifier_call_chain+0x9/0x16 <-- [<ffffffff8020abba>] __exit_idle+0x2c/0x2e
  CPU 1:  [<ffffffff804946e9>] __atomic_notifier_call_chain+0xe/0x56 <-- [<ffffffff80494745>] atomic_notifier_call_chain+0x14/0x16
  CPU 1:  [<ffffffff80494691>] notifier_call_chain+0x16/0x60 <-- [<ffffffff80494701>] __atomic_notifier_call_chain+0x26/0x56
  CPU 1:  [<ffffffff802161c8>] mce_idle_callback+0x9/0x2f <-- [<ffffffff804946b3>] notifier_call_chain+0x38/0x60

This is in the format of the output when KALLSYMS is defined.

  CPU <CPU#>: [<IP>] <func> <-- [<Parent-IP>] <parent-func>

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
 lib/tracing/tracer.c |  217 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 215 insertions(+), 2 deletions(-)

Index: linux-compile.git/lib/tracing/tracer.c
===================================================================
--- linux-compile.git.orig/lib/tracing/tracer.c	2008-01-14 13:14:13.000000000 -0500
+++ linux-compile.git/lib/tracing/tracer.c	2008-01-14 14:57:58.000000000 -0500
@@ -13,9 +13,11 @@
 #include <linux/fs.h>
 #include <linux/gfp.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/linkage.h>
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
+#include <linux/kallsyms.h>
 #include <linux/uaccess.h>
 #include <linux/mcount.h>
 
@@ -23,6 +25,7 @@
 #include "tracer_interface.h"
 
 static struct mctracer_trace mctracer_trace;
+static int trace_enabled __read_mostly;
 
 static inline notrace void
 mctracer_add_trace_entry(struct mctracer_trace *tr,
@@ -62,7 +65,7 @@ static notrace void trace_function(const
 	raw_local_irq_save(flags);
 
 	tr = &mctracer_trace;
-	if (!tr->ctrl)
+	if (!trace_enabled)
 		goto out;
 
 	cpu = raw_smp_processor_id();
@@ -83,6 +86,205 @@ static struct mcount_ops trace_ops __rea
 };
 
 #ifdef CONFIG_DEBUG_FS
+struct mctracer_iterator {
+	struct mctracer_trace *tr;
+	struct mctracer_entry *ent;
+	unsigned long next_idx[NR_CPUS];
+	int cpu;
+	int idx;
+};
+
+static struct mctracer_entry *mctracer_entry_idx(struct mctracer_trace *tr,
+						 unsigned long idx,
+						 int cpu)
+{
+	struct mctracer_entry *array = tr->trace[cpu];
+	unsigned long underrun;
+
+	if (idx >= tr->entries)
+		return NULL;
+
+	underrun = atomic_read(&tr->underrun[cpu]);
+	if (underrun)
+		idx = ((underrun - 1) + idx) % tr->entries;
+	else if (idx >= tr->trace_idx[cpu])
+		return NULL;
+
+	return &array[idx];
+}
+
+static void *find_next_entry(struct mctracer_iterator *iter)
+{
+	struct mctracer_trace *tr = iter->tr;
+	struct mctracer_entry *ent;
+	struct mctracer_entry *next = NULL;
+	int next_i = -1;
+	int i;
+
+	for_each_possible_cpu(i) {
+		if (!tr->trace[i])
+			continue;
+		ent = mctracer_entry_idx(tr, iter->next_idx[i], i);
+		if (ent && (!next || next->idx > ent->idx)) {
+			next = ent;
+			next_i = i;
+		}
+	}
+	if (next) {
+		iter->next_idx[next_i]++;
+		iter->idx++;
+	}
+	iter->ent = next;
+	iter->cpu = next_i;
+
+	return next ? iter : NULL;
+}
+
+static void *s_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct mctracer_iterator *iter = m->private;
+	void *ent;
+	int i = (int)*pos;
+
+	(*pos)++;
+
+	/* can't go backwards */
+	if (iter->idx > i)
+		return NULL;
+
+	if (iter->idx < 0)
+		ent = find_next_entry(iter);
+	else
+		ent = iter;
+
+	while (ent && iter->idx < i)
+		ent = find_next_entry(iter);
+
+	return ent;
+}
+
+static void *s_start(struct seq_file *m, loff_t *pos)
+{
+	struct mctracer_iterator *iter = m->private;
+	void *p = NULL;
+	loff_t l = 0;
+	int i;
+
+	iter->ent = NULL;
+	iter->cpu = 0;
+	iter->idx = -1;
+
+	for (i = 0; i < NR_CPUS; i++)
+		iter->next_idx[i] = 0;
+
+	/* stop the trace while dumping */
+	if (iter->tr->ctrl)
+		trace_enabled = 0;
+
+	for (p = iter; p && l < *pos; p = s_next(m, p, &l))
+		;
+
+	return p;
+}
+
+static void s_stop(struct seq_file *m, void *p)
+{
+	struct mctracer_iterator *iter = m->private;
+	if (iter->tr->ctrl)
+		trace_enabled = 1;
+}
+
+#ifdef CONFIG_KALLSYMS
+static void seq_print_symbol(struct seq_file *m,
+			     const char *fmt, unsigned long address)
+{
+	char buffer[KSYM_SYMBOL_LEN];
+
+	sprint_symbol(buffer, address);
+	seq_printf(m, fmt, buffer);
+}
+#else
+# define seq_print_symbol(m, fmt, address) do { } while (0)
+#endif
+
+#ifndef CONFIG_64BIT
+# define IP_FMT "%08lx"
+#else
+# define IP_FMT "%016lx"
+#endif
+
+static void notrace seq_print_ip_sym(struct seq_file *m,
+				     unsigned long ip)
+{
+	seq_print_symbol(m, "%s", ip);
+	seq_printf(m, " <" IP_FMT ">", ip);
+}
+
+static int s_show(struct seq_file *m, void *v)
+{
+	struct mctracer_iterator *iter = v;
+
+	if (iter->ent == NULL) {
+		seq_printf(m, "mctracer:\n");
+	} else {
+		seq_printf(m, "  CPU %d:  ", iter->cpu);
+		seq_print_ip_sym(m, iter->ent->ip);
+		if (iter->ent->parent_ip) {
+			seq_printf(m, " <-- ");
+			seq_print_ip_sym(m, iter->ent->parent_ip);
+		}
+		seq_printf(m, "\n");
+	}
+
+	return 0;
+}
+
+static struct seq_operations mctrace_seq_ops = {
+	.start = s_start,
+	.next = s_next,
+	.stop = s_stop,
+	.show = s_show,
+};
+
+static int mctrace_open(struct inode *inode, struct file *file)
+{
+	struct mctracer_iterator *iter;
+	int ret;
+
+	iter = kzalloc(sizeof(*iter), GFP_KERNEL);
+	if (!iter)
+		return -ENOMEM;
+
+	iter->tr = &mctracer_trace;
+
+	/* TODO stop tracer */
+	ret = seq_open(file, &mctrace_seq_ops);
+	if (!ret) {
+		struct seq_file *m = file->private_data;
+		m->private = iter;
+	} else
+		kfree(iter);
+
+	return ret;
+}
+
+int mctrace_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *m = (struct seq_file *)file->private_data;
+	struct mctracer_iterator *iter = m->private;
+
+	seq_release(inode, file);
+	kfree(iter);
+	return 0;
+}
+
+static struct file_operations mctrace_fops = {
+	.open = mctrace_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = mctrace_release,
+};
+
 static int mctracer_open_generic(struct inode *inode, struct file *filp)
 {
 	filp->private_data = inode->i_private;
@@ -120,7 +322,13 @@ static ssize_t mctracer_ctrl_write(struc
 
 	val = !!simple_strtoul(buf, NULL, 10);
 
-	tr->ctrl = val;
+	if (tr->ctrl ^ val) {
+		if (val)
+			trace_enabled = 1;
+		else
+			trace_enabled = 0;
+		tr->ctrl = val;
+	}
 
 	filp->f_pos += cnt;
 
@@ -148,6 +356,11 @@ static void mctrace_init_debugfs(void)
 				    &mctracer_trace, &mctracer_ctrl_fops);
 	if (!entry)
 		pr_warning("Could not create debugfs 'ctrl' entry\n");
+
+	entry = debugfs_create_file("trace", 0444, d_mctracer,
+				    &mctracer_trace, &mctrace_fops);
+	if (!entry)
+		pr_warning("Could not create debugfs 'trace' entry\n");
 }
 #else /* CONFIG_DEBUG_FS */
 static void mctrace_init_debugfs(void)

-- 

  parent reply	other threads:[~2008-01-15 20:51 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-15 20:49 [RFC PATCH 00/30 v3] mcount and latency tracing utility -v3 Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 01/30 v3] Add basic support for gcc profiler instrumentation Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 02/30 v3] Annotate core code that should not be traced Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 03/30 v3] x86_64: notrace annotations Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 04/30 v3] add notrace annotations to vsyscall Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 05/30 v3] add notrace annotations for NMI routines Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 06/30 v3] mcount based trace in the form of a header file library Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 07/30 v3] tracer add debugfs interface Steven Rostedt
2008-01-15 20:49 ` Steven Rostedt [this message]
2008-01-15 20:49 ` [RFC PATCH 09/30 v3] mcount tracer show task comm and pid Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 10/30 v3] Add a symbol only trace output Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 11/30 v3] Reset the tracer when started Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 12/30 v3] separate out the percpu date into a percpu struct Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 13/30 v3] handle accurate time keeping over long delays Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 14/30 v3] ppc clock accumulate fix Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 15/30 v3] Fixup merge between xtime_cache and timkkeeping starvation fix Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 16/30 v3] time keeping add cycle_raw for actual incrementation Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 17/30 v3] initialize the clock source to jiffies clock Steven Rostedt
2008-01-15 21:14   ` Mathieu Desnoyers
2008-01-15 21:27     ` Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 18/30 v3] add get_monotonic_cycles Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 19/30 v3] add notrace annotations to timing events Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 20/30 v3] Add timestamps to tracer Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 21/30 v3] Sort trace by timestamp Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 22/30 v3] speed up the output of the tracer Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 23/30 v3] Add latency_trace format tor tracer Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 24/30 v3] Split out specific tracing functions Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 25/30 v3] Trace irq disabled critical timings Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 26/30 v3] Add context switch marker to sched.c Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 27/30 v3] Add tracing of context switches Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 28/30 v3] Generic command line storage Steven Rostedt
2008-01-15 21:30   ` Mathieu Desnoyers
2008-01-15 22:15     ` Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 29/30 v3] make varaible size buffers for traces Steven Rostedt
2008-01-15 20:49 ` [RFC PATCH 30/30 v3] trace preempt off critical timings Steven Rostedt

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=20080115205022.585424916@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=acme@ghostprotocols.net \
    --cc=akpm@linux-foundation.org \
    --cc=fche@redhat.com \
    --cc=ghaskins@novell.com \
    --cc=hch@infradead.org \
    --cc=jan.kiszka@siemens.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@polymtl.ca \
    --cc=mingo@elte.hu \
    --cc=sam@ravnborg.org \
    --cc=srostedt@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=tim.bird@am.sony.com \
    --cc=torvalds@linux-foundation.org \
    /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