summaryrefslogtreecommitdiff
path: root/tools/perf/util/auxtrace.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2015-04-30 17:37:31 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-05-05 18:13:00 -0300
commitd20031bb63dd6dde35feb7845eaf17c620eef120 (patch)
treeb36fd419c0ef1459ef4cfe1b000e1b4a3c65e6f2 /tools/perf/util/auxtrace.c
parent0ad21f6869222fd7fd7c63f02febea082e801fc2 (diff)
perf tools: Add AUX area tracing Snapshot Mode
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>
Diffstat (limited to 'tools/perf/util/auxtrace.c')
-rw-r--r--tools/perf/util/auxtrace.c85
1 files changed, 75 insertions, 10 deletions
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 129371048fc1..df66966cfde7 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