From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Thomas Gleixner <tglx@linutronix.de>,
Frederic Weisbecker <fweisbec@gmail.com>,
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
David Sharp <dhsharp@google.com>,
Vaibhav Nagarnaik <vnagarnaik@google.com>,
hcochran@lexmark.com,
Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>,
Peter Zijlstra <peterz@infradead.org>
Subject: [for-next][PATCH 15/17] tracing: Add internal tracing_snapshot() functions
Date: Thu, 07 Mar 2013 22:00:13 -0500 [thread overview]
Message-ID: <20130308030654.221050352@goodmis.org> (raw)
In-Reply-To: 20130308025958.501479677@goodmis.org
[-- Attachment #1: 0015-tracing-Add-internal-tracing_snapshot-functions.patch --]
[-- Type: text/plain, Size: 5603 bytes --]
From: "Steven Rostedt (Red Hat)" <srostedt@redhat.com>
The new snapshot feature is quite handy. It's a way for the user
to take advantage of the spare buffer that, until then, only
the latency tracers used to "snapshot" the buffer when it hit
a max latency. Now users can trigger a "snapshot" manually when
some condition is hit in a program. But a snapshot currently can
not be triggered by a condition inside the kernel.
With the addition of tracing_snapshot() and tracing_snapshot_alloc(),
snapshots can now be taking when a condition is hit, and the
developer wants to snapshot the case without stopping the trace.
Note, any snapshot will overwrite the old one, so take care
in how this is done.
These new functions are to be used like tracing_on(), tracing_off()
and trace_printk() are. That is, they should never be called
in the mainline Linux kernel. They are solely for the purpose
of debugging.
The tracing_snapshot() will not allocate a buffer, but it is
safe to be called from any context (except NMIs). But if a
snapshot buffer isn't allocated when it is called, it will write
to the live buffer, complaining about the lack of a snapshot
buffer, and then stop tracing (giving you the "permanent snapshot").
tracing_snapshot_alloc() will allocate the snapshot buffer if
it was not already allocated and then take the snapshot. This routine
*may sleep*, and must be called from context that can sleep.
The allocation is done with GFP_KERNEL and not atomic.
If you need a snapshot in an atomic context, say in early boot,
then it is best to call the tracing_snapshot_alloc() before then,
where it will allocate the buffer, and then you can use the
tracing_snapshot() anywhere you want and still get snapshots.
Cc: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
include/linux/kernel.h | 4 +++
kernel/trace/trace.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index c566927..bc5392a 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -483,6 +483,8 @@ enum ftrace_dump_mode {
void tracing_on(void);
void tracing_off(void);
int tracing_is_on(void);
+void tracing_snapshot(void);
+void tracing_snapshot_alloc(void);
extern void tracing_start(void);
extern void tracing_stop(void);
@@ -570,6 +572,8 @@ static inline void trace_dump_stack(void) { }
static inline void tracing_on(void) { }
static inline void tracing_off(void) { }
static inline int tracing_is_on(void) { return 0; }
+static inline void tracing_snapshot(void) { }
+static inline void tracing_snapshot_alloc(void) { }
static inline __printf(1, 2)
int trace_printk(const char *fmt, ...)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8ede7d1..c15ba8b 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -339,6 +339,90 @@ void tracing_on(void)
}
EXPORT_SYMBOL_GPL(tracing_on);
+#ifdef CONFIG_TRACER_SNAPSHOT
+/**
+ * trace_snapshot - take a snapshot of the current buffer.
+ *
+ * This causes a swap between the snapshot buffer and the current live
+ * tracing buffer. You can use this to take snapshots of the live
+ * trace when some condition is triggered, but continue to trace.
+ *
+ * Note, make sure to allocate the snapshot with either
+ * a tracing_snapshot_alloc(), or by doing it manually
+ * with: echo 1 > /sys/kernel/debug/tracing/snapshot
+ *
+ * If the snapshot buffer is not allocated, it will stop tracing.
+ * Basically making a permanent snapshot.
+ */
+void tracing_snapshot(void)
+{
+ struct trace_array *tr = &global_trace;
+ struct tracer *tracer = tr->current_trace;
+ unsigned long flags;
+
+ if (!tr->allocated_snapshot) {
+ trace_printk("*** SNAPSHOT NOT ALLOCATED ***\n");
+ trace_printk("*** stopping trace here! ***\n");
+ tracing_off();
+ return;
+ }
+
+ /* Note, snapshot can not be used when the tracer uses it */
+ if (tracer->use_max_tr) {
+ trace_printk("*** LATENCY TRACER ACTIVE ***\n");
+ trace_printk("*** Can not use snapshot (sorry) ***\n");
+ return;
+ }
+
+ local_irq_save(flags);
+ update_max_tr(tr, current, smp_processor_id());
+ local_irq_restore(flags);
+}
+
+static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
+ struct trace_buffer *size_buf, int cpu_id);
+
+/**
+ * trace_snapshot_alloc - allocate and take a snapshot of the current buffer.
+ *
+ * This is similar to trace_snapshot(), but it will allocate the
+ * snapshot buffer if it isn't already allocated. Use this only
+ * where it is safe to sleep, as the allocation may sleep.
+ *
+ * This causes a swap between the snapshot buffer and the current live
+ * tracing buffer. You can use this to take snapshots of the live
+ * trace when some condition is triggered, but continue to trace.
+ */
+void tracing_snapshot_alloc(void)
+{
+ struct trace_array *tr = &global_trace;
+ int ret;
+
+ if (!tr->allocated_snapshot) {
+
+ /* allocate spare buffer */
+ ret = resize_buffer_duplicate_size(&tr->max_buffer,
+ &tr->trace_buffer, RING_BUFFER_ALL_CPUS);
+ if (WARN_ON(ret < 0))
+ return;
+
+ tr->allocated_snapshot = true;
+ }
+
+ tracing_snapshot();
+}
+#else
+void tracing_snapshot(void)
+{
+ WARN_ONCE(1, "Snapshot feature not enabled, but internal snapshot used");
+}
+void tracing_snapshot_alloc(void)
+{
+ /* Give warning */
+ tracing_snapshot();
+}
+#endif /* CONFIG_TRACER_SNAPSHOT */
+
/**
* tracing_off - turn off tracing buffers
*
--
1.7.10.4
next prev parent reply other threads:[~2013-03-08 3:07 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-08 2:59 [for-next][PATCH 00/17] tracing: multi-buffers with snapshots, per_cpu and some debugging tools Steven Rostedt
2013-03-08 2:59 ` [for-next][PATCH 01/17] ring-buffer: Init waitqueue for blocked readers Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 02/17] tracing: Add comment for trace event flag IGNORE_ENABLE Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 03/17] tracing: Only clear trace buffer on module unload if event was traced Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 04/17] tracing: Clear all trace buffers when unloaded module event was used Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 05/17] tracing: Enable snapshot when any latency tracer is enabled Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 06/17] tracing: Consolidate max_tr into main trace_array structure Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 07/17] tracing: Add snapshot in the per_cpu trace directories Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 08/17] tracing: Add config option to allow snapshot to swap per cpu Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 09/17] tracing: Add snapshot_raw to extract the raw data from snapshot Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 10/17] tracing: Have trace_array keep track if snapshot buffer is allocated Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 11/17] tracing: Consolidate buffer allocation code Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 12/17] tracing: Add snapshot feature to instances Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 13/17] tracing: Add per_cpu directory into tracing instances Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 14/17] tracing: Prevent deleting instances when they are being read Steven Rostedt
2013-03-08 3:00 ` Steven Rostedt [this message]
2013-03-08 3:00 ` [for-next][PATCH 16/17] ring-buffer: Do not use schedule_work_on() for current CPU Steven Rostedt
2013-03-08 3:00 ` [for-next][PATCH 17/17] tracing: Move the tracing selftest code into its own function 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=20130308030654.221050352@goodmis.org \
--to=rostedt@goodmis.org \
--cc=akpm@linux-foundation.org \
--cc=dhsharp@google.com \
--cc=fweisbec@gmail.com \
--cc=hcochran@lexmark.com \
--cc=hiraku.toyooka.gu@hitachi.com \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=vnagarnaik@google.com \
/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