From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org,
Adrian Hunter <adrian.hunter@intel.com>,
David Ahern <dsahern@gmail.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Namhyung Kim <namhyung@gmail.com>,
Peter Zijlstra <peterz@infradead.org>,
Stephane Eranian <eranian@google.com>,
Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 08/25] perf tools: Add AUX area tracing Snapshot Mode
Date: Tue, 5 May 2015 18:32:02 -0300 [thread overview]
Message-ID: <1430861539-30518-9-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1430861539-30518-1-git-send-email-acme@kernel.org>
From: Adrian Hunter <adrian.hunter@intel.com>
Add support for making snapshots of AUX area tracing data.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1430404667-10593-9-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/perf.h | 3 ++
tools/perf/util/auxtrace.c | 85 ++++++++++++++++++++++++++++++++++++++++------
tools/perf/util/auxtrace.h | 41 ++++++++++++++++++++++
3 files changed, 119 insertions(+), 10 deletions(-)
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 5042093..aa79fb8 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -55,6 +55,7 @@ struct record_opts {
bool sample_intr_regs;
bool running_time;
bool full_auxtrace;
+ bool auxtrace_snapshot_mode;
unsigned int freq;
unsigned int mmap_pages;
unsigned int auxtrace_mmap_pages;
@@ -62,6 +63,8 @@ struct record_opts {
u64 branch_stack;
u64 default_interval;
u64 user_interval;
+ size_t auxtrace_snapshot_size;
+ const char *auxtrace_snapshot_opts;
bool sample_transaction;
unsigned initial_delay;
bool use_clockid;
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 1293710..df66966 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -504,6 +504,29 @@ void auxtrace_record__free(struct auxtrace_record *itr)
itr->free(itr);
}
+int auxtrace_record__snapshot_start(struct auxtrace_record *itr)
+{
+ if (itr && itr->snapshot_start)
+ return itr->snapshot_start(itr);
+ return 0;
+}
+
+int auxtrace_record__snapshot_finish(struct auxtrace_record *itr)
+{
+ if (itr && itr->snapshot_finish)
+ return itr->snapshot_finish(itr);
+ return 0;
+}
+
+int auxtrace_record__find_snapshot(struct auxtrace_record *itr, int idx,
+ struct auxtrace_mmap *mm,
+ unsigned char *data, u64 *head, u64 *old)
+{
+ if (itr && itr->find_snapshot)
+ return itr->find_snapshot(itr, idx, mm, data, head, old);
+ return 0;
+}
+
int auxtrace_record__options(struct auxtrace_record *itr,
struct perf_evlist *evlist,
struct record_opts *opts)
@@ -520,6 +543,19 @@ u64 auxtrace_record__reference(struct auxtrace_record *itr)
return 0;
}
+int auxtrace_parse_snapshot_options(struct auxtrace_record *itr,
+ struct record_opts *opts, const char *str)
+{
+ if (!str)
+ return 0;
+
+ if (itr)
+ return itr->parse_snapshot_options(itr, opts, str);
+
+ pr_err("No AUX area tracing to snapshot\n");
+ return -EINVAL;
+}
+
struct auxtrace_record *__weak
auxtrace_record__init(struct perf_evlist *evlist __maybe_unused, int *err)
{
@@ -1077,16 +1113,26 @@ int perf_event__process_auxtrace_error(struct perf_tool *tool __maybe_unused,
return 0;
}
-int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
- struct perf_tool *tool, process_auxtrace_t fn)
+static int __auxtrace_mmap__read(struct auxtrace_mmap *mm,
+ struct auxtrace_record *itr,
+ struct perf_tool *tool, process_auxtrace_t fn,
+ bool snapshot, size_t snapshot_size)
{
- u64 head = auxtrace_mmap__read_head(mm);
- u64 old = mm->prev, offset, ref;
+ u64 head, old = mm->prev, offset, ref;
unsigned char *data = mm->base;
size_t size, head_off, old_off, len1, len2, padding;
union perf_event ev;
void *data1, *data2;
+ if (snapshot) {
+ head = auxtrace_mmap__read_snapshot_head(mm);
+ if (auxtrace_record__find_snapshot(itr, mm->idx, mm, data,
+ &head, &old))
+ return -1;
+ } else {
+ head = auxtrace_mmap__read_head(mm);
+ }
+
if (old == head)
return 0;
@@ -1106,6 +1152,9 @@ int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
else
size = mm->len - (old_off - head_off);
+ if (snapshot && size > snapshot_size)
+ size = snapshot_size;
+
ref = auxtrace_record__reference(itr);
if (head > old || size <= head || mm->mask) {
@@ -1153,18 +1202,34 @@ int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
mm->prev = head;
- auxtrace_mmap__write_tail(mm, head);
- if (itr->read_finish) {
- int err;
+ if (!snapshot) {
+ auxtrace_mmap__write_tail(mm, head);
+ if (itr->read_finish) {
+ int err;
- err = itr->read_finish(itr, mm->idx);
- if (err < 0)
- return err;
+ err = itr->read_finish(itr, mm->idx);
+ if (err < 0)
+ return err;
+ }
}
return 1;
}
+int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
+ struct perf_tool *tool, process_auxtrace_t fn)
+{
+ return __auxtrace_mmap__read(mm, itr, tool, fn, false, 0);
+}
+
+int auxtrace_mmap__read_snapshot(struct auxtrace_mmap *mm,
+ struct auxtrace_record *itr,
+ struct perf_tool *tool, process_auxtrace_t fn,
+ size_t snapshot_size)
+{
+ return __auxtrace_mmap__read(mm, itr, tool, fn, true, snapshot_size);
+}
+
/**
* struct auxtrace_cache - hash table to implement a cache
* @hashtable: the hashtable
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 8c6cbb1..c2c677e 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -276,6 +276,10 @@ struct auxtrace_mmap_params {
* @info_priv_size: return the size of the private data in auxtrace_info_event
* @info_fill: fill-in the private data in auxtrace_info_event
* @free: free this auxtrace record structure
+ * @snapshot_start: starting a snapshot
+ * @snapshot_finish: finishing a snapshot
+ * @find_snapshot: find data to snapshot within auxtrace mmap
+ * @parse_snapshot_options: parse snapshot options
* @reference: provide a 64-bit reference number for auxtrace_event
* @read_finish: called after reading from an auxtrace mmap
*/
@@ -289,12 +293,36 @@ struct auxtrace_record {
struct auxtrace_info_event *auxtrace_info,
size_t priv_size);
void (*free)(struct auxtrace_record *itr);
+ int (*snapshot_start)(struct auxtrace_record *itr);
+ int (*snapshot_finish)(struct auxtrace_record *itr);
+ int (*find_snapshot)(struct auxtrace_record *itr, int idx,
+ struct auxtrace_mmap *mm, unsigned char *data,
+ u64 *head, u64 *old);
+ int (*parse_snapshot_options)(struct auxtrace_record *itr,
+ struct record_opts *opts,
+ const char *str);
u64 (*reference)(struct auxtrace_record *itr);
int (*read_finish)(struct auxtrace_record *itr, int idx);
};
#ifdef HAVE_AUXTRACE_SUPPORT
+/*
+ * In snapshot mode the mmapped page is read-only which makes using
+ * __sync_val_compare_and_swap() problematic. However, snapshot mode expects
+ * the buffer is not updated while the snapshot is made (e.g. Intel PT disables
+ * the event) so there is not a race anyway.
+ */
+static inline u64 auxtrace_mmap__read_snapshot_head(struct auxtrace_mmap *mm)
+{
+ struct perf_event_mmap_page *pc = mm->userpg;
+ u64 head = ACCESS_ONCE(pc->aux_head);
+
+ /* Ensure all reads are done after we read the head */
+ rmb();
+ return head;
+}
+
static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
{
struct perf_event_mmap_page *pc = mm->userpg;
@@ -346,6 +374,11 @@ typedef int (*process_auxtrace_t)(struct perf_tool *tool,
int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
struct perf_tool *tool, process_auxtrace_t fn);
+int auxtrace_mmap__read_snapshot(struct auxtrace_mmap *mm,
+ struct auxtrace_record *itr,
+ struct perf_tool *tool, process_auxtrace_t fn,
+ size_t snapshot_size);
+
int auxtrace_queues__init(struct auxtrace_queues *queues);
int auxtrace_queues__add_event(struct auxtrace_queues *queues,
struct perf_session *session,
@@ -383,6 +416,9 @@ void *auxtrace_cache__lookup(struct auxtrace_cache *c, u32 key);
struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist,
int *err);
+int auxtrace_parse_snapshot_options(struct auxtrace_record *itr,
+ struct record_opts *opts,
+ const char *str);
int auxtrace_record__options(struct auxtrace_record *itr,
struct perf_evlist *evlist,
struct record_opts *opts);
@@ -392,6 +428,11 @@ int auxtrace_record__info_fill(struct auxtrace_record *itr,
struct auxtrace_info_event *auxtrace_info,
size_t priv_size);
void auxtrace_record__free(struct auxtrace_record *itr);
+int auxtrace_record__snapshot_start(struct auxtrace_record *itr);
+int auxtrace_record__snapshot_finish(struct auxtrace_record *itr);
+int auxtrace_record__find_snapshot(struct auxtrace_record *itr, int idx,
+ struct auxtrace_mmap *mm,
+ unsigned char *data, u64 *head, u64 *old);
u64 auxtrace_record__reference(struct auxtrace_record *itr);
int auxtrace_index__auxtrace_event(struct list_head *head, union perf_event *event,
--
2.1.0
next prev parent reply other threads:[~2015-05-05 21:37 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-05 21:31 [GIT PULL 00/25] perf/core improvements and fixes Arnaldo Carvalho de Melo
2015-05-05 21:31 ` Arnaldo Carvalho de Melo
2015-05-05 21:31 ` [PATCH 01/25] perf report: Fix placement of itrace option in documentation Arnaldo Carvalho de Melo
2015-05-05 21:31 ` [PATCH 02/25] perf tools: Add AUX area tracing index Arnaldo Carvalho de Melo
2015-05-05 21:31 ` [PATCH 03/25] perf tools: Hit all build ids when AUX area tracing Arnaldo Carvalho de Melo
2015-05-05 21:31 ` [PATCH 04/25] perf tools: Add build option NO_AUXTRACE to exclude " Arnaldo Carvalho de Melo
2015-05-05 21:31 ` [PATCH 05/25] perf auxtrace: Add option to synthesize events for transactions Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 06/25] perf tools: Add support for PERF_RECORD_AUX Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 07/25] perf tools: Add support for PERF_RECORD_ITRACE_START Arnaldo Carvalho de Melo
2015-05-05 21:32 ` Arnaldo Carvalho de Melo [this message]
2015-05-05 21:32 ` [PATCH 09/25] perf record: Add AUX area tracing Snapshot Mode support Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 10/25] perf probe: Allow to use filter on --del command Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 11/25] perf probe: Accept filter argument for --funcs Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 12/25] perf probe: Remove redundant cleanup of params.filter Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 13/25] perf probe: Cleanup and consolidate command parsers Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 14/25] perf kmem: Show warning when trying to run stat without record Arnaldo Carvalho de Melo
2015-05-05 21:32 ` Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 15/25] perf tools: Move TUI-specific fields into unnamed union Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 16/25] perf tools: Move init_have_children field to the " Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 17/25] perf hists browser: Fix possible memory leak Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 18/25] perf hists browser: Save hist_browser_timer pointer in hist_browser Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 19/25] perf hists browser: Save pstack in the hist_browser Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 20/25] perf hists browser: Save perf_session_env " Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 21/25] perf hists browser: Split popup menu actions Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 22/25] perf hists browser: Split popup menu actions - part 2 Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 23/25] perf tools: Introduce pstack_peek() Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 24/25] perf hists browser: Simplify zooming code using pstack_peek() Arnaldo Carvalho de Melo
2015-05-05 21:32 ` [PATCH 25/25] perf tools: Move TUI-specific fields out of map_symbol Arnaldo Carvalho de Melo
2015-05-06 2:47 ` [GIT PULL 00/25] perf/core improvements and fixes Ingo Molnar
2015-05-06 2:47 ` Ingo Molnar
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=1430861539-30518-9-git-send-email-acme@kernel.org \
--to=acme@kernel.org \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=dsahern@gmail.com \
--cc=eranian@google.com \
--cc=fweisbec@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@gmail.com \
--cc=peterz@infradead.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.