aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2016-09-28 07:41:36 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-10-05 07:15:58 -0400
commit3bccbe20f6d188ce7b00326e776b745cfd35b10a (patch)
treed612443434cfe4540c2fd6cd47e761c4d6141a2c /tools/perf/util
parent51ee6481fa8e879cc942bcc1b0af713e158b7a98 (diff)
perf intel-pt: Fix MTC timestamp calculation for large MTC periods
The MTC packet provides a 8-bit slice of CTC which is related to TSC by the TMA packet, however the TMA packet only provides the lower 16 bits of CTC. If mtc_shift > 8 then some of the MTC bits are not in the CTC provided by the TMA packet. Fix-up the last_mtc calculated from the TMA packet by copying the missing bits from the current MTC assuming the least difference between the two, and that the current MTC comes after last_mtc. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: stable@vger.kernel.org # v4.3+ Link: http://lkml.kernel.org/r/1475062896-22274-2-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-decoder.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 3d1d446f037f..16c06d3ae577 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -90,6 +90,7 @@ struct intel_pt_decoder {
90 bool pge; 90 bool pge;
91 bool have_tma; 91 bool have_tma;
92 bool have_cyc; 92 bool have_cyc;
93 bool fixup_last_mtc;
93 uint64_t pos; 94 uint64_t pos;
94 uint64_t last_ip; 95 uint64_t last_ip;
95 uint64_t ip; 96 uint64_t ip;
@@ -586,10 +587,31 @@ struct intel_pt_calc_cyc_to_tsc_info {
586 uint64_t tsc_timestamp; 587 uint64_t tsc_timestamp;
587 uint64_t timestamp; 588 uint64_t timestamp;
588 bool have_tma; 589 bool have_tma;
590 bool fixup_last_mtc;
589 bool from_mtc; 591 bool from_mtc;
590 double cbr_cyc_to_tsc; 592 double cbr_cyc_to_tsc;
591}; 593};
592 594
595/*
596 * MTC provides a 8-bit slice of CTC but the TMA packet only provides the lower
597 * 16 bits of CTC. If mtc_shift > 8 then some of the MTC bits are not in the CTC
598 * provided by the TMA packet. Fix-up the last_mtc calculated from the TMA
599 * packet by copying the missing bits from the current MTC assuming the least
600 * difference between the two, and that the current MTC comes after last_mtc.
601 */
602static void intel_pt_fixup_last_mtc(uint32_t mtc, int mtc_shift,
603 uint32_t *last_mtc)
604{
605 uint32_t first_missing_bit = 1U << (16 - mtc_shift);
606 uint32_t mask = ~(first_missing_bit - 1);
607
608 *last_mtc |= mtc & mask;
609 if (*last_mtc >= mtc) {
610 *last_mtc -= first_missing_bit;
611 *last_mtc &= 0xff;
612 }
613}
614
593static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) 615static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
594{ 616{
595 struct intel_pt_decoder *decoder = pkt_info->decoder; 617 struct intel_pt_decoder *decoder = pkt_info->decoder;
@@ -619,6 +641,11 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
619 return 0; 641 return 0;
620 642
621 mtc = pkt_info->packet.payload; 643 mtc = pkt_info->packet.payload;
644 if (decoder->mtc_shift > 8 && data->fixup_last_mtc) {
645 data->fixup_last_mtc = false;
646 intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift,
647 &data->last_mtc);
648 }
622 if (mtc > data->last_mtc) 649 if (mtc > data->last_mtc)
623 mtc_delta = mtc - data->last_mtc; 650 mtc_delta = mtc - data->last_mtc;
624 else 651 else
@@ -687,6 +714,7 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
687 714
688 data->ctc_delta = 0; 715 data->ctc_delta = 0;
689 data->have_tma = true; 716 data->have_tma = true;
717 data->fixup_last_mtc = true;
690 718
691 return 0; 719 return 0;
692 720
@@ -753,6 +781,7 @@ static void intel_pt_calc_cyc_to_tsc(struct intel_pt_decoder *decoder,
753 .tsc_timestamp = decoder->tsc_timestamp, 781 .tsc_timestamp = decoder->tsc_timestamp,
754 .timestamp = decoder->timestamp, 782 .timestamp = decoder->timestamp,
755 .have_tma = decoder->have_tma, 783 .have_tma = decoder->have_tma,
784 .fixup_last_mtc = decoder->fixup_last_mtc,
756 .from_mtc = from_mtc, 785 .from_mtc = from_mtc,
757 .cbr_cyc_to_tsc = 0, 786 .cbr_cyc_to_tsc = 0,
758 }; 787 };
@@ -1271,6 +1300,7 @@ static void intel_pt_calc_tma(struct intel_pt_decoder *decoder)
1271 } 1300 }
1272 decoder->ctc_delta = 0; 1301 decoder->ctc_delta = 0;
1273 decoder->have_tma = true; 1302 decoder->have_tma = true;
1303 decoder->fixup_last_mtc = true;
1274 intel_pt_log("CTC timestamp " x64_fmt " last MTC %#x CTC rem %#x\n", 1304 intel_pt_log("CTC timestamp " x64_fmt " last MTC %#x CTC rem %#x\n",
1275 decoder->ctc_timestamp, decoder->last_mtc, ctc_rem); 1305 decoder->ctc_timestamp, decoder->last_mtc, ctc_rem);
1276} 1306}
@@ -1285,6 +1315,12 @@ static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder)
1285 1315
1286 mtc = decoder->packet.payload; 1316 mtc = decoder->packet.payload;
1287 1317
1318 if (decoder->mtc_shift > 8 && decoder->fixup_last_mtc) {
1319 decoder->fixup_last_mtc = false;
1320 intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift,
1321 &decoder->last_mtc);
1322 }
1323
1288 if (mtc > decoder->last_mtc) 1324 if (mtc > decoder->last_mtc)
1289 mtc_delta = mtc - decoder->last_mtc; 1325 mtc_delta = mtc - decoder->last_mtc;
1290 else 1326 else