perf tools: Add guest_cpu to hypervisor threads
authorAdrian Hunter <adrian.hunter@intel.com>
Mon, 11 Jul 2022 09:31:55 +0000 (12:31 +0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 20 Jul 2022 14:08:04 +0000 (11:08 -0300)
It is possible to know which guest machine was running at a point in time
based on the PID of the currently running host thread. That is, perf
identifies guest machines by the PID of the hypervisor.

To determine the guest CPU, put it on the hypervisor (QEMU) thread for
that VCPU.

This is done when processing the id_index which provides the necessary
information.

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-13-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/session.c
tools/perf/util/thread.c
tools/perf/util/thread.h

index 1af981d5ad3c7d5654358d8fac96928741735595..91a091c359450ca4388f5fda95b0eaf5a8e2338c 100644 (file)
@@ -2769,6 +2769,20 @@ static int perf_session__register_guest(struct perf_session *session, pid_t mach
        return 0;
 }
 
+static int perf_session__set_guest_cpu(struct perf_session *session, pid_t pid,
+                                      pid_t tid, int guest_cpu)
+{
+       struct machine *machine = &session->machines.host;
+       struct thread *thread = machine__findnew_thread(machine, pid, tid);
+
+       if (!thread)
+               return -ENOMEM;
+       thread->guest_cpu = guest_cpu;
+       thread__put(thread);
+
+       return 0;
+}
+
 int perf_event__process_id_index(struct perf_session *session,
                                 union perf_event *event)
 {
@@ -2845,6 +2859,10 @@ int perf_event__process_id_index(struct perf_session *session,
                        last_pid = sid->machine_pid;
                        perf_guest = true;
                }
+
+               ret = perf_session__set_guest_cpu(session, sid->machine_pid, e->tid, e2->vcpu);
+               if (ret)
+                       return ret;
        }
        return 0;
 }
index 665e5c0618ed3d330ff1bc0238f9bc1a3d4cdee7..e3e5427e1c3c8702d23854bd7643923a6752a372 100644 (file)
@@ -47,6 +47,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
                thread->tid = tid;
                thread->ppid = -1;
                thread->cpu = -1;
+               thread->guest_cpu = -1;
                thread->lbr_stitch_enable = false;
                INIT_LIST_HEAD(&thread->namespaces_list);
                INIT_LIST_HEAD(&thread->comm_list);
index b066fb30d203da8eb87ace26fb3998b4a1ee3fad..241f300d7d6ef468856cfcdcc84462a979e53f73 100644 (file)
@@ -39,6 +39,7 @@ struct thread {
        pid_t                   tid;
        pid_t                   ppid;
        int                     cpu;
+       int                     guest_cpu; /* For QEMU thread */
        refcount_t              refcnt;
        bool                    comm_set;
        int                     comm_len;