diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2022-07-11 11:31:53 +0200 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2022-07-20 16:07:58 +0200 |
commit | b47bb18661eaed30790d70b7563a5220b3c59594 (patch) | |
tree | 457ad457fa1a80154ebb02f1ff0e3806ae4a70a5 /tools/perf/util/synthetic-events.c | |
parent | perf buildid-cache: Do not require purge files to also be in the file system (diff) | |
download | linux-b47bb18661eaed30790d70b7563a5220b3c59594.tar.xz linux-b47bb18661eaed30790d70b7563a5220b3c59594.zip |
perf tools: Add machine_pid and vcpu to id_index
When injecting events from a guest perf.data file, the events will have
separate sample ID numbers. These ID numbers can then be used to determine
which machine an event belongs to. To facilitate that, add machine_pid and
vcpu to id_index records. For backward compatibility, these are added at
the end of the record, and the length of the record is used to determine
if they are present or not.
Note, this is needed because the events from a guest perf.data file contain
the pid/tid of the process running at that time inside the VM not the
pid/tid of the (QEMU) hypervisor thread. So a way is needed to relate
guest events back to the guest machine and VCPU, and using sample ID
numbers for that is relatively simple and convenient.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: kvm@vger.kernel.org
Link: https://lore.kernel.org/r/20220711093218.10967-11-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/synthetic-events.c')
-rw-r--r-- | tools/perf/util/synthetic-events.c | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index ed9623702f34..2ae59c03ae77 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1759,19 +1759,26 @@ int perf_event__synthesize_id_sample(__u64 *array, u64 type, const struct perf_s return (void *)array - (void *)start; } -int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, - struct evlist *evlist, struct machine *machine) +int __perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, + struct evlist *evlist, struct machine *machine, size_t from) { union perf_event *ev; struct evsel *evsel; - size_t nr = 0, i = 0, sz, max_nr, n; + size_t nr = 0, i = 0, sz, max_nr, n, pos; + size_t e1_sz = sizeof(struct id_index_entry); + size_t e2_sz = sizeof(struct id_index_entry_2); + size_t etot_sz = e1_sz + e2_sz; + bool e2_needed = false; int err; - max_nr = (UINT16_MAX - sizeof(struct perf_record_id_index)) / - sizeof(struct id_index_entry); + max_nr = (UINT16_MAX - sizeof(struct perf_record_id_index)) / etot_sz; - evlist__for_each_entry(evlist, evsel) + pos = 0; + evlist__for_each_entry(evlist, evsel) { + if (pos++ < from) + continue; nr += evsel->core.ids; + } if (!nr) return 0; @@ -1779,31 +1786,38 @@ int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_ pr_debug2("Synthesizing id index\n"); n = nr > max_nr ? max_nr : nr; - sz = sizeof(struct perf_record_id_index) + n * sizeof(struct id_index_entry); + sz = sizeof(struct perf_record_id_index) + n * etot_sz; ev = zalloc(sz); if (!ev) return -ENOMEM; + sz = sizeof(struct perf_record_id_index) + n * e1_sz; + ev->id_index.header.type = PERF_RECORD_ID_INDEX; - ev->id_index.header.size = sz; ev->id_index.nr = n; + pos = 0; evlist__for_each_entry(evlist, evsel) { u32 j; - for (j = 0; j < evsel->core.ids; j++) { + if (pos++ < from) + continue; + for (j = 0; j < evsel->core.ids; j++, i++) { struct id_index_entry *e; + struct id_index_entry_2 *e2; struct perf_sample_id *sid; if (i >= n) { + ev->id_index.header.size = sz + (e2_needed ? n * e2_sz : 0); err = process(tool, ev, NULL, machine); if (err) goto out_err; nr -= n; i = 0; + e2_needed = false; } - e = &ev->id_index.entries[i++]; + e = &ev->id_index.entries[i]; e->id = evsel->core.id[j]; @@ -1816,11 +1830,18 @@ int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_ e->idx = sid->idx; e->cpu = sid->cpu.cpu; e->tid = sid->tid; + + if (sid->machine_pid) + e2_needed = true; + + e2 = (void *)ev + sz; + e2[i].machine_pid = sid->machine_pid; + e2[i].vcpu = sid->vcpu.cpu; } } - sz = sizeof(struct perf_record_id_index) + nr * sizeof(struct id_index_entry); - ev->id_index.header.size = sz; + sz = sizeof(struct perf_record_id_index) + nr * e1_sz; + ev->id_index.header.size = sz + (e2_needed ? nr * e2_sz : 0); ev->id_index.nr = nr; err = process(tool, ev, NULL, machine); @@ -1830,6 +1851,12 @@ out_err: return err; } +int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, + struct evlist *evlist, struct machine *machine) +{ + return __perf_event__synthesize_id_index(tool, process, evlist, machine, 0); +} + int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, struct target *target, struct perf_thread_map *threads, perf_event__handler_t process, bool needs_mmap, |