summaryrefslogtreecommitdiff
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2022-07-11 12:31:53 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2022-07-20 11:07:58 -0300
commitb47bb18661eaed30790d70b7563a5220b3c59594 (patch)
tree457ad457fa1a80154ebb02f1ff0e3806ae4a70a5 /tools/perf/util/session.c
parentc1fd5b7d8aed8104d5189c3d55545d67f9149bb6 (diff)
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/session.c')
-rw-r--r--tools/perf/util/session.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 4c9513bc6d89..5141fe164e97 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2756,18 +2756,35 @@ int perf_event__process_id_index(struct perf_session *session,
{
struct evlist *evlist = session->evlist;
struct perf_record_id_index *ie = &event->id_index;
+ size_t sz = ie->header.size - sizeof(*ie);
size_t i, nr, max_nr;
+ 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;
+ struct id_index_entry_2 *e2;
- max_nr = (ie->header.size - sizeof(struct perf_record_id_index)) /
- sizeof(struct id_index_entry);
+ max_nr = sz / e1_sz;
nr = ie->nr;
- if (nr > max_nr)
+ if (nr > max_nr) {
+ printf("Too big: nr %zu max_nr %zu\n", nr, max_nr);
return -EINVAL;
+ }
+
+ if (sz >= nr * etot_sz) {
+ max_nr = sz / etot_sz;
+ if (nr > max_nr) {
+ printf("Too big2: nr %zu max_nr %zu\n", nr, max_nr);
+ return -EINVAL;
+ }
+ e2 = (void *)ie + sizeof(*ie) + nr * e1_sz;
+ } else {
+ e2 = NULL;
+ }
if (dump_trace)
fprintf(stdout, " nr: %zu\n", nr);
- for (i = 0; i < nr; i++) {
+ for (i = 0; i < nr; i++, (e2 ? e2++ : 0)) {
struct id_index_entry *e = &ie->entries[i];
struct perf_sample_id *sid;
@@ -2775,15 +2792,28 @@ int perf_event__process_id_index(struct perf_session *session,
fprintf(stdout, " ... id: %"PRI_lu64, e->id);
fprintf(stdout, " idx: %"PRI_lu64, e->idx);
fprintf(stdout, " cpu: %"PRI_ld64, e->cpu);
- fprintf(stdout, " tid: %"PRI_ld64"\n", e->tid);
+ fprintf(stdout, " tid: %"PRI_ld64, e->tid);
+ if (e2) {
+ fprintf(stdout, " machine_pid: %"PRI_ld64, e2->machine_pid);
+ fprintf(stdout, " vcpu: %"PRI_lu64"\n", e2->vcpu);
+ } else {
+ fprintf(stdout, "\n");
+ }
}
sid = evlist__id2sid(evlist, e->id);
if (!sid)
return -ENOENT;
+
sid->idx = e->idx;
sid->cpu.cpu = e->cpu;
sid->tid = e->tid;
+
+ if (!e2)
+ continue;
+
+ sid->machine_pid = e2->machine_pid;
+ sid->vcpu.cpu = e2->vcpu;
}
return 0;
}