Skip to content

Commit 9f31645

Browse files
ahunter6ksacilotto
authored andcommitted
perf intel-pt: Fix premature IPC
BugLink: https://bugs.launchpad.net/bugs/1918974 [ Upstream commit 20aa397 ] The code assumed a change in cycle count means accurate IPC. That is not correct, for example when sampling both branches and instructions, or at a FUP packet (which is not CYC-eligible) address. Fix by using an explicit flag to indicate when IPC can be sampled. Fixes: 5b1dc0f ("perf intel-pt: Add support for samples to contain IPC ratio") Signed-off-by: Adrian Hunter <[email protected]> Reviewed-by: Andi Kleen <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Kamal Mostafa <[email protected]> Signed-off-by: Kelsey Skunberg <[email protected]>
1 parent 161bf17 commit 9f31645

File tree

3 files changed

+17
-11
lines changed

3 files changed

+17
-11
lines changed

tools/perf/util/intel-pt-decoder/intel-pt-decoder.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2637,9 +2637,18 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
26372637
}
26382638
if (intel_pt_sample_time(decoder->pkt_state)) {
26392639
intel_pt_update_sample_time(decoder);
2640-
if (decoder->sample_cyc)
2640+
if (decoder->sample_cyc) {
26412641
decoder->sample_tot_cyc_cnt = decoder->tot_cyc_cnt;
2642+
decoder->state.flags |= INTEL_PT_SAMPLE_IPC;
2643+
decoder->sample_cyc = false;
2644+
}
26422645
}
2646+
/*
2647+
* When using only TSC/MTC to compute cycles, IPC can be
2648+
* sampled as soon as the cycle count changes.
2649+
*/
2650+
if (!decoder->have_cyc)
2651+
decoder->state.flags |= INTEL_PT_SAMPLE_IPC;
26432652
}
26442653

26452654
decoder->state.timestamp = decoder->sample_timestamp;

tools/perf/util/intel-pt-decoder/intel-pt-decoder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define INTEL_PT_ABORT_TX (1 << 1)
1818
#define INTEL_PT_ASYNC (1 << 2)
1919
#define INTEL_PT_FUP_IP (1 << 3)
20+
#define INTEL_PT_SAMPLE_IPC (1 << 4)
2021

2122
enum intel_pt_sample_type {
2223
INTEL_PT_BRANCH = 1 << 0,

tools/perf/util/intel-pt.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,8 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
13041304
sample.branch_stack = (struct branch_stack *)&dummy_bs;
13051305
}
13061306

1307-
sample.cyc_cnt = ptq->ipc_cyc_cnt - ptq->last_br_cyc_cnt;
1307+
if (ptq->state->flags & INTEL_PT_SAMPLE_IPC)
1308+
sample.cyc_cnt = ptq->ipc_cyc_cnt - ptq->last_br_cyc_cnt;
13081309
if (sample.cyc_cnt) {
13091310
sample.insn_cnt = ptq->ipc_insn_cnt - ptq->last_br_insn_cnt;
13101311
ptq->last_br_insn_cnt = ptq->ipc_insn_cnt;
@@ -1366,7 +1367,8 @@ static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
13661367
sample.stream_id = ptq->pt->instructions_id;
13671368
sample.period = ptq->state->tot_insn_cnt - ptq->last_insn_cnt;
13681369

1369-
sample.cyc_cnt = ptq->ipc_cyc_cnt - ptq->last_in_cyc_cnt;
1370+
if (ptq->state->flags & INTEL_PT_SAMPLE_IPC)
1371+
sample.cyc_cnt = ptq->ipc_cyc_cnt - ptq->last_in_cyc_cnt;
13701372
if (sample.cyc_cnt) {
13711373
sample.insn_cnt = ptq->ipc_insn_cnt - ptq->last_in_insn_cnt;
13721374
ptq->last_in_insn_cnt = ptq->ipc_insn_cnt;
@@ -1901,14 +1903,8 @@ static int intel_pt_sample(struct intel_pt_queue *ptq)
19011903

19021904
ptq->have_sample = false;
19031905

1904-
if (ptq->state->tot_cyc_cnt > ptq->ipc_cyc_cnt) {
1905-
/*
1906-
* Cycle count and instruction count only go together to create
1907-
* a valid IPC ratio when the cycle count changes.
1908-
*/
1909-
ptq->ipc_insn_cnt = ptq->state->tot_insn_cnt;
1910-
ptq->ipc_cyc_cnt = ptq->state->tot_cyc_cnt;
1911-
}
1906+
ptq->ipc_insn_cnt = ptq->state->tot_insn_cnt;
1907+
ptq->ipc_cyc_cnt = ptq->state->tot_cyc_cnt;
19121908

19131909
/*
19141910
* Do PEBS first to allow for the possibility that the PEBS timestamp

0 commit comments

Comments
 (0)