perf intel-pt: Track guest context switches
authorAdrian Hunter <adrian.hunter@intel.com>
Mon, 11 Jul 2022 09:32:13 +0000 (12:32 +0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 20 Jul 2022 14:08:49 +0000 (11:08 -0300)
Use guest context switch events to keep track of which guest thread is
running on a particular guest machine and VCPU.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Andi Kleen <ak@linux.intel.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-31-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/intel-pt.c

index a8798b5..98b097f 100644 (file)
@@ -78,6 +78,7 @@ struct intel_pt {
        bool use_thread_stack;
        bool callstack;
        bool cap_event_trace;
+       bool have_guest_sideband;
        unsigned int br_stack_sz;
        unsigned int br_stack_sz_plus;
        int have_sched_switch;
@@ -3079,6 +3080,25 @@ static int intel_pt_context_switch_in(struct intel_pt *pt,
        return machine__set_current_tid(pt->machine, cpu, pid, tid);
 }
 
+static int intel_pt_guest_context_switch(struct intel_pt *pt,
+                                        union perf_event *event,
+                                        struct perf_sample *sample)
+{
+       bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
+       struct machines *machines = &pt->session->machines;
+       struct machine *machine = machines__find(machines, sample->machine_pid);
+
+       pt->have_guest_sideband = true;
+
+       if (out)
+               return 0;
+
+       if (!machine)
+               return -EINVAL;
+
+       return machine__set_current_tid(machine, sample->vcpu, sample->pid, sample->tid);
+}
+
 static int intel_pt_context_switch(struct intel_pt *pt, union perf_event *event,
                                   struct perf_sample *sample)
 {
@@ -3086,6 +3106,9 @@ static int intel_pt_context_switch(struct intel_pt *pt, union perf_event *event,
        pid_t pid, tid;
        int cpu, ret;
 
+       if (perf_event__is_guest(event))
+               return intel_pt_guest_context_switch(pt, event, sample);
+
        cpu = sample->cpu;
 
        if (pt->have_sched_switch == 3) {