ftrace: add sysprof plugin
authorIngo Molnar <mingo@elte.hu>
Mon, 12 May 2008 19:20:47 +0000 (21:20 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 23 May 2008 21:39:00 +0000 (23:39 +0200)
very first baby version.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/trace_sysprof.c [new file with mode: 0644]

index 5c2295b..e101c9a 100644 (file)
@@ -75,6 +75,14 @@ config PREEMPT_TRACER
          enabled. This option and the irqs-off timing option can be
          used together or separately.)
 
+config SYSPROF_TRACER
+       bool "Sysprof Tracer"
+       depends on DEBUG_KERNEL
+       select TRACING
+       help
+         This tracer provides the trace needed by the 'Sysprof' userspace
+         tool.
+
 config SCHED_TRACER
        bool "Scheduling Latency Tracer"
        depends on HAVE_FTRACE
index d9efbbf..7aec123 100644 (file)
@@ -14,6 +14,7 @@ obj-$(CONFIG_FTRACE) += libftrace.o
 
 obj-$(CONFIG_TRACING) += trace.o
 obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
+obj-$(CONFIG_SYSPROF_TRACER) += trace_sysprof.o
 obj-$(CONFIG_FTRACE) += trace_functions.o
 obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o
 obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o
diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c
new file mode 100644 (file)
index 0000000..6c139bc
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * trace stack traces
+ *
+ * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com>
+ * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
+ *
+ */
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
+#include <linux/marker.h>
+#include <linux/ftrace.h>
+
+#include "trace.h"
+
+static struct trace_array      *ctx_trace;
+static int __read_mostly       tracer_enabled;
+
+static notrace void stack_reset(struct trace_array *tr)
+{
+       int cpu;
+
+       tr->time_start = ftrace_now(tr->cpu);
+
+       for_each_online_cpu(cpu)
+               tracing_reset(tr->data[cpu]);
+}
+
+static notrace void start_stack_trace(struct trace_array *tr)
+{
+       stack_reset(tr);
+       tracer_enabled = 1;
+}
+
+static notrace void stop_stack_trace(struct trace_array *tr)
+{
+       tracer_enabled = 0;
+}
+
+static notrace void stack_trace_init(struct trace_array *tr)
+{
+       ctx_trace = tr;
+
+       if (tr->ctrl)
+               start_stack_trace(tr);
+}
+
+static notrace void stack_trace_reset(struct trace_array *tr)
+{
+       if (tr->ctrl)
+               stop_stack_trace(tr);
+}
+
+static void stack_trace_ctrl_update(struct trace_array *tr)
+{
+       /* When starting a new trace, reset the buffers */
+       if (tr->ctrl)
+               start_stack_trace(tr);
+       else
+               stop_stack_trace(tr);
+}
+
+static struct tracer stack_trace __read_mostly =
+{
+       .name           = "sysprof",
+       .init           = stack_trace_init,
+       .reset          = stack_trace_reset,
+       .ctrl_update    = stack_trace_ctrl_update,
+#ifdef CONFIG_FTRACE_SELFTEST
+       .selftest    = trace_selftest_startup_stack,
+#endif
+};
+
+__init static int init_stack_trace(void)
+{
+       return register_tracer(&stack_trace);
+}
+device_initcall(init_stack_trace);