]>
Commit | Line | Data |
---|---|---|
dc13a30d GKH |
1 | From 61b6e08dc8e3ea80b7485c9b3f875ddd45c8466b Mon Sep 17 00:00:00 2001 |
2 | From: Adrian Hunter <adrian.hunter@intel.com> | |
3 | Date: Fri, 10 May 2019 15:41:42 +0300 | |
4 | Subject: perf intel-pt: Fix improved sample timestamp | |
5 | ||
6 | From: Adrian Hunter <adrian.hunter@intel.com> | |
7 | ||
8 | commit 61b6e08dc8e3ea80b7485c9b3f875ddd45c8466b upstream. | |
9 | ||
10 | The decoder uses its current timestamp in samples. Usually that is a | |
11 | timestamp that has already passed, but in some cases it is a timestamp | |
12 | for a branch that the decoder is walking towards, and consequently | |
13 | hasn't reached. | |
14 | ||
15 | The intel_pt_sample_time() function decides which is which, but was not | |
16 | handling TNT packets exactly correctly. | |
17 | ||
18 | In the case of TNT, the timestamp applies to the first branch, so the | |
19 | decoder must first walk to that branch. | |
20 | ||
21 | That means intel_pt_sample_time() should return true for TNT, and this | |
22 | patch makes that change. However, if the first branch is a non-taken | |
23 | branch (i.e. a 'N'), then intel_pt_sample_time() needs to return false | |
24 | for subsequent taken branches in the same TNT packet. | |
25 | ||
26 | To handle that, introduce a new state INTEL_PT_STATE_TNT_CONT to | |
27 | distinguish the cases. | |
28 | ||
29 | Note that commit 3f04d98e972b5 ("perf intel-pt: Improve sample | |
30 | timestamp") was also a stable fix and appears, for example, in v4.4 | |
31 | stable tree as commit a4ebb58fd124 ("perf intel-pt: Improve sample | |
32 | timestamp"). | |
33 | ||
34 | Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> | |
35 | Cc: Jiri Olsa <jolsa@redhat.com> | |
36 | Cc: stable@vger.kernel.org # v4.4+ | |
37 | Fixes: 3f04d98e972b5 ("perf intel-pt: Improve sample timestamp") | |
38 | Link: http://lkml.kernel.org/r/20190510124143.27054-3-adrian.hunter@intel.com | |
39 | Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> | |
40 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
41 | ||
42 | --- | |
43 | tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 13 ++++++++++--- | |
44 | 1 file changed, 10 insertions(+), 3 deletions(-) | |
45 | ||
46 | --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | |
47 | +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | |
48 | @@ -58,6 +58,7 @@ enum intel_pt_pkt_state { | |
49 | INTEL_PT_STATE_NO_IP, | |
50 | INTEL_PT_STATE_ERR_RESYNC, | |
51 | INTEL_PT_STATE_IN_SYNC, | |
52 | + INTEL_PT_STATE_TNT_CONT, | |
53 | INTEL_PT_STATE_TNT, | |
54 | INTEL_PT_STATE_TIP, | |
55 | INTEL_PT_STATE_TIP_PGD, | |
56 | @@ -72,8 +73,9 @@ static inline bool intel_pt_sample_time( | |
57 | case INTEL_PT_STATE_NO_IP: | |
58 | case INTEL_PT_STATE_ERR_RESYNC: | |
59 | case INTEL_PT_STATE_IN_SYNC: | |
60 | - case INTEL_PT_STATE_TNT: | |
61 | + case INTEL_PT_STATE_TNT_CONT: | |
62 | return true; | |
63 | + case INTEL_PT_STATE_TNT: | |
64 | case INTEL_PT_STATE_TIP: | |
65 | case INTEL_PT_STATE_TIP_PGD: | |
66 | case INTEL_PT_STATE_FUP: | |
67 | @@ -1261,7 +1263,9 @@ static int intel_pt_walk_tnt(struct inte | |
68 | return -ENOENT; | |
69 | } | |
70 | decoder->tnt.count -= 1; | |
71 | - if (!decoder->tnt.count) | |
72 | + if (decoder->tnt.count) | |
73 | + decoder->pkt_state = INTEL_PT_STATE_TNT_CONT; | |
74 | + else | |
75 | decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; | |
76 | decoder->tnt.payload <<= 1; | |
77 | decoder->state.from_ip = decoder->ip; | |
78 | @@ -1292,7 +1296,9 @@ static int intel_pt_walk_tnt(struct inte | |
79 | ||
80 | if (intel_pt_insn.branch == INTEL_PT_BR_CONDITIONAL) { | |
81 | decoder->tnt.count -= 1; | |
82 | - if (!decoder->tnt.count) | |
83 | + if (decoder->tnt.count) | |
84 | + decoder->pkt_state = INTEL_PT_STATE_TNT_CONT; | |
85 | + else | |
86 | decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; | |
87 | if (decoder->tnt.payload & BIT63) { | |
88 | decoder->tnt.payload <<= 1; | |
89 | @@ -2372,6 +2378,7 @@ const struct intel_pt_state *intel_pt_de | |
90 | err = intel_pt_walk_trace(decoder); | |
91 | break; | |
92 | case INTEL_PT_STATE_TNT: | |
93 | + case INTEL_PT_STATE_TNT_CONT: | |
94 | err = intel_pt_walk_tnt(decoder); | |
95 | if (err == -EAGAIN) | |
96 | err = intel_pt_walk_trace(decoder); |