diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2016-09-28 07:41:36 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-10-05 07:15:58 -0400 |
commit | 3bccbe20f6d188ce7b00326e776b745cfd35b10a (patch) | |
tree | d612443434cfe4540c2fd6cd47e761c4d6141a2c /tools/perf/util | |
parent | 51ee6481fa8e879cc942bcc1b0af713e158b7a98 (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.c | 36 |
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 | */ | ||
602 | static 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 | |||
593 | static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info) | 615 | static 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 |