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/intel-pt-decoder | |
| 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/intel-pt-decoder')
| -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 |
