perf intel-pt: Pass the first timestamp to the decoder
authorAdrian Hunter <adrian.hunter@intel.com>
Fri, 30 Apr 2021 07:03:06 +0000 (10:03 +0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 12 May 2021 15:43:11 +0000 (12:43 -0300)
VM Time Correlation will use time ranges to determine whether a TSC packet
belongs to the Host or Guest. To start, the first non-zero timestamp is
needed. Pass that to the decoder.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: https://lore.kernel.org/r/20210430070309.17624-10-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
tools/perf/util/intel-pt.c

index c12e4a3..7c93ae2 100644 (file)
@@ -140,6 +140,7 @@ struct intel_pt_decoder {
        uint64_t ctc_delta;
        uint64_t cycle_cnt;
        uint64_t cyc_ref_timestamp;
+       uint64_t first_timestamp;
        uint32_t last_mtc;
        uint32_t tsc_ctc_ratio_n;
        uint32_t tsc_ctc_ratio_d;
@@ -265,6 +266,7 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
        decoder->branch_enable      = params->branch_enable;
        decoder->hop                = params->quick >= 1;
        decoder->leap               = params->quick >= 2;
+       decoder->first_timestamp    = params->first_timestamp;
 
        decoder->flags              = params->flags;
 
@@ -314,6 +316,12 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
        return decoder;
 }
 
+void intel_pt_set_first_timestamp(struct intel_pt_decoder *decoder,
+                                 uint64_t first_timestamp)
+{
+       decoder->first_timestamp = first_timestamp;
+}
+
 static void intel_pt_pop_blk(struct intel_pt_stack *stack)
 {
        struct intel_pt_blk *blk = stack->blk;
index e6e782d..4d78a8c 100644 (file)
@@ -258,6 +258,7 @@ struct intel_pt_params {
        void *data;
        bool return_compression;
        bool branch_enable;
+       uint64_t first_timestamp;
        uint64_t ctl;
        uint64_t period;
        enum intel_pt_period_type period_type;
@@ -285,4 +286,7 @@ unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a,
 
 int intel_pt__strerror(int code, char *buf, size_t buflen);
 
+void intel_pt_set_first_timestamp(struct intel_pt_decoder *decoder,
+                                 uint64_t first_timestamp);
+
 #endif
index 8f6df8e..858b679 100644 (file)
@@ -78,6 +78,7 @@ struct intel_pt {
        u64 kernel_start;
        u64 switch_ip;
        u64 ptss_ip;
+       u64 first_timestamp;
 
        struct perf_tsc_conversion tc;
        bool cap_user_time_zero;
@@ -1181,6 +1182,7 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,
        params.tsc_ctc_ratio_n = pt->tsc_ctc_ratio_n;
        params.tsc_ctc_ratio_d = pt->tsc_ctc_ratio_d;
        params.quick = pt->synth_opts.quick;
+       params.first_timestamp = pt->first_timestamp;
 
        if (pt->filts.cnt > 0)
                params.pgd_ip = intel_pt_pgd_ip;
@@ -1245,6 +1247,21 @@ static void intel_pt_free_queue(void *priv)
        free(ptq);
 }
 
+static void intel_pt_first_timestamp(struct intel_pt *pt, u64 timestamp)
+{
+       unsigned int i;
+
+       pt->first_timestamp = timestamp;
+
+       for (i = 0; i < pt->queues.nr_queues; i++) {
+               struct auxtrace_queue *queue = &pt->queues.queue_array[i];
+               struct intel_pt_queue *ptq = queue->priv;
+
+               if (ptq && ptq->decoder)
+                       intel_pt_set_first_timestamp(ptq->decoder, timestamp);
+       }
+}
+
 static void intel_pt_set_pid_tid_cpu(struct intel_pt *pt,
                                     struct auxtrace_queue *queue)
 {
@@ -2947,6 +2964,8 @@ static int intel_pt_process_event(struct perf_session *session,
                                                               sample->time);
                }
        } else if (timestamp) {
+               if (!pt->first_timestamp)
+                       intel_pt_first_timestamp(pt, timestamp);
                err = intel_pt_process_queues(pt, timestamp);
        }
        if (err)