summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/auxtrace.c
diff options
context:
space:
mode:
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
OpenPOWER on IntegriCloud