[tip:perf/core] tracing: Make a snapshot feature available from userspace

2013-02-03 Thread tip-bot for Hiraku Toyooka
Commit-ID:  debdd57f5145f3c6a4b3f8d0126abd1a2def7fc6
Gitweb: http://git.kernel.org/tip/debdd57f5145f3c6a4b3f8d0126abd1a2def7fc6
Author: Hiraku Toyooka 
AuthorDate: Wed, 26 Dec 2012 11:53:00 +0900
Committer:  Steven Rostedt 
CommitDate: Wed, 30 Jan 2013 11:02:06 -0500

tracing: Make a snapshot feature available from userspace

Ftrace has a snapshot feature available from kernel space and
latency tracers (e.g. irqsoff) are using it. This patch enables
user applictions to take a snapshot via debugfs.

Add "snapshot" debugfs file in "tracing" directory.

  snapshot:
This is used to take a snapshot and to read the output of the
snapshot.

 # echo 1 > snapshot

This will allocate the spare buffer for snapshot (if it is
not allocated), and take a snapshot.

 # cat snapshot

This will show contents of the snapshot.

 # echo 0 > snapshot

This will free the snapshot if it is allocated.

Any other positive values will clear the snapshot contents if
the snapshot is allocated, or return EINVAL if it is not allocated.

Link: http://lkml.kernel.org/r/20121226025300.3252.86850.stgit@liselsia

Cc: Jiri Olsa 
Cc: David Sharp 
Signed-off-by: Hiraku Toyooka 
[
   Fixed irqsoff selftest and also a conflict with a change
   that fixes the update_max_tr.
]
Signed-off-by: Steven Rostedt 
---
 include/linux/ftrace_event.h |   3 +
 kernel/trace/Kconfig |  10 +++
 kernel/trace/trace.c | 166 ---
 kernel/trace/trace.h |   1 +
 4 files changed, 154 insertions(+), 26 deletions(-)

diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 6f8d0b7..13a54d0 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -83,6 +83,9 @@ struct trace_iterator {
longidx;
 
cpumask_var_t   started;
+
+   /* it's true when current open file is snapshot */
+   boolsnapshot;
 };
 
 enum trace_iter_flags {
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index cdc9d28..3656756 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -253,6 +253,16 @@ config FTRACE_SYSCALLS
help
  Basic tracer to catch the syscall entry and exit events.
 
+config TRACER_SNAPSHOT
+   bool "Create a snapshot trace buffer"
+   select TRACER_MAX_TRACE
+   help
+ Allow tracing users to take snapshot of the current buffer using the
+ ftrace interface, e.g.:
+
+ echo 1 > /sys/kernel/debug/tracing/snapshot
+ cat snapshot
+
 config TRACE_BRANCH_PROFILING
bool
select GENERIC_TRACER
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2c72466..70dce64 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -710,12 +710,11 @@ update_max_tr(struct trace_array *tr, struct task_struct 
*tsk, int cpu)
 
WARN_ON_ONCE(!irqs_disabled());
 
-   /* If we disabled the tracer, stop now */
-   if (current_trace == _trace)
-   return;
-
-   if (WARN_ON_ONCE(!current_trace->use_max_tr))
+   if (!current_trace->allocated_snapshot) {
+   /* Only the nop tracer should hit this when disabling */
+   WARN_ON_ONCE(current_trace != _trace);
return;
+   }
 
arch_spin_lock(_max_lock);
 
@@ -743,10 +742,8 @@ update_max_tr_single(struct trace_array *tr, struct 
task_struct *tsk, int cpu)
return;
 
WARN_ON_ONCE(!irqs_disabled());
-   if (!current_trace->use_max_tr) {
-   WARN_ON_ONCE(1);
+   if (WARN_ON_ONCE(!current_trace->allocated_snapshot))
return;
-   }
 
arch_spin_lock(_max_lock);
 
@@ -866,10 +863,13 @@ int register_tracer(struct tracer *type)
 
current_trace = type;
 
-   /* If we expanded the buffers, make sure the max is expanded 
too */
-   if (ring_buffer_expanded && type->use_max_tr)
-   ring_buffer_resize(max_tr.buffer, trace_buf_size,
-   RING_BUFFER_ALL_CPUS);
+   if (type->use_max_tr) {
+   /* If we expanded the buffers, make sure the max is 
expanded too */
+   if (ring_buffer_expanded)
+   ring_buffer_resize(max_tr.buffer, 
trace_buf_size,
+  RING_BUFFER_ALL_CPUS);
+   type->allocated_snapshot = true;
+   }
 
/* the test is responsible for initializing and enabling */
pr_info("Testing tracer %s: ", type->name);
@@ -885,10 +885,14 @@ int register_tracer(struct tracer *type)
/* Only reset on passing, to avoid touching corrupted buffers */
tracing_reset_online_cpus(tr);
 
-   /* Shrink the max buffer again */
-   if (ring_buffer_expanded && 

[tip:perf/core] tracing: Make a snapshot feature available from userspace

2013-02-03 Thread tip-bot for Hiraku Toyooka
Commit-ID:  debdd57f5145f3c6a4b3f8d0126abd1a2def7fc6
Gitweb: http://git.kernel.org/tip/debdd57f5145f3c6a4b3f8d0126abd1a2def7fc6
Author: Hiraku Toyooka hiraku.toyooka...@hitachi.com
AuthorDate: Wed, 26 Dec 2012 11:53:00 +0900
Committer:  Steven Rostedt rost...@goodmis.org
CommitDate: Wed, 30 Jan 2013 11:02:06 -0500

tracing: Make a snapshot feature available from userspace

Ftrace has a snapshot feature available from kernel space and
latency tracers (e.g. irqsoff) are using it. This patch enables
user applictions to take a snapshot via debugfs.

Add snapshot debugfs file in tracing directory.

  snapshot:
This is used to take a snapshot and to read the output of the
snapshot.

 # echo 1  snapshot

This will allocate the spare buffer for snapshot (if it is
not allocated), and take a snapshot.

 # cat snapshot

This will show contents of the snapshot.

 # echo 0  snapshot

This will free the snapshot if it is allocated.

Any other positive values will clear the snapshot contents if
the snapshot is allocated, or return EINVAL if it is not allocated.

Link: http://lkml.kernel.org/r/20121226025300.3252.86850.stgit@liselsia

Cc: Jiri Olsa jo...@redhat.com
Cc: David Sharp dhsh...@google.com
Signed-off-by: Hiraku Toyooka hiraku.toyooka...@hitachi.com
[
   Fixed irqsoff selftest and also a conflict with a change
   that fixes the update_max_tr.
]
Signed-off-by: Steven Rostedt rost...@goodmis.org
---
 include/linux/ftrace_event.h |   3 +
 kernel/trace/Kconfig |  10 +++
 kernel/trace/trace.c | 166 ---
 kernel/trace/trace.h |   1 +
 4 files changed, 154 insertions(+), 26 deletions(-)

diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 6f8d0b7..13a54d0 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -83,6 +83,9 @@ struct trace_iterator {
longidx;
 
cpumask_var_t   started;
+
+   /* it's true when current open file is snapshot */
+   boolsnapshot;
 };
 
 enum trace_iter_flags {
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index cdc9d28..3656756 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -253,6 +253,16 @@ config FTRACE_SYSCALLS
help
  Basic tracer to catch the syscall entry and exit events.
 
+config TRACER_SNAPSHOT
+   bool Create a snapshot trace buffer
+   select TRACER_MAX_TRACE
+   help
+ Allow tracing users to take snapshot of the current buffer using the
+ ftrace interface, e.g.:
+
+ echo 1  /sys/kernel/debug/tracing/snapshot
+ cat snapshot
+
 config TRACE_BRANCH_PROFILING
bool
select GENERIC_TRACER
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2c72466..70dce64 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -710,12 +710,11 @@ update_max_tr(struct trace_array *tr, struct task_struct 
*tsk, int cpu)
 
WARN_ON_ONCE(!irqs_disabled());
 
-   /* If we disabled the tracer, stop now */
-   if (current_trace == nop_trace)
-   return;
-
-   if (WARN_ON_ONCE(!current_trace-use_max_tr))
+   if (!current_trace-allocated_snapshot) {
+   /* Only the nop tracer should hit this when disabling */
+   WARN_ON_ONCE(current_trace != nop_trace);
return;
+   }
 
arch_spin_lock(ftrace_max_lock);
 
@@ -743,10 +742,8 @@ update_max_tr_single(struct trace_array *tr, struct 
task_struct *tsk, int cpu)
return;
 
WARN_ON_ONCE(!irqs_disabled());
-   if (!current_trace-use_max_tr) {
-   WARN_ON_ONCE(1);
+   if (WARN_ON_ONCE(!current_trace-allocated_snapshot))
return;
-   }
 
arch_spin_lock(ftrace_max_lock);
 
@@ -866,10 +863,13 @@ int register_tracer(struct tracer *type)
 
current_trace = type;
 
-   /* If we expanded the buffers, make sure the max is expanded 
too */
-   if (ring_buffer_expanded  type-use_max_tr)
-   ring_buffer_resize(max_tr.buffer, trace_buf_size,
-   RING_BUFFER_ALL_CPUS);
+   if (type-use_max_tr) {
+   /* If we expanded the buffers, make sure the max is 
expanded too */
+   if (ring_buffer_expanded)
+   ring_buffer_resize(max_tr.buffer, 
trace_buf_size,
+  RING_BUFFER_ALL_CPUS);
+   type-allocated_snapshot = true;
+   }
 
/* the test is responsible for initializing and enabling */
pr_info(Testing tracer %s: , type-name);
@@ -885,10 +885,14 @@ int register_tracer(struct tracer *type)
/* Only reset on passing, to avoid touching corrupted buffers */