Skip to content

Commit c79ee2b

Browse files
ahunter6acmel
authored andcommitted
perf intel-pt: Fix state setting when receiving overflow (OVF) packet
An overflow (OVF packet) is treated as an error because it represents a loss of trace data, but there is no loss of synchronization, so the packet state should be INTEL_PT_STATE_IN_SYNC not INTEL_PT_STATE_ERR_RESYNC. To support that, some additional variables must be reset, and the FUP packet that may follow OVF is treated as an FUP event. Fixes: f4aa081 ("perf tools: Add Intel PT decoder") Signed-off-by: Adrian Hunter <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: [email protected] # v5.15+ Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 4c761d8 commit c79ee2b

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

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

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,20 @@ static bool intel_pt_fup_event(struct intel_pt_decoder *decoder)
12491249
decoder->state.type |= INTEL_PT_BLK_ITEMS;
12501250
ret = true;
12511251
}
1252+
if (decoder->overflow) {
1253+
decoder->overflow = false;
1254+
if (!ret && !decoder->pge) {
1255+
if (decoder->hop) {
1256+
decoder->state.type = 0;
1257+
decoder->pkt_state = INTEL_PT_STATE_RESAMPLE;
1258+
}
1259+
decoder->pge = true;
1260+
decoder->state.type |= INTEL_PT_BRANCH | INTEL_PT_TRACE_BEGIN;
1261+
decoder->state.from_ip = 0;
1262+
decoder->state.to_ip = decoder->ip;
1263+
return true;
1264+
}
1265+
}
12521266
if (ret) {
12531267
decoder->state.from_ip = decoder->ip;
12541268
decoder->state.to_ip = 0;
@@ -1602,7 +1616,16 @@ static int intel_pt_overflow(struct intel_pt_decoder *decoder)
16021616
intel_pt_clear_tx_flags(decoder);
16031617
intel_pt_set_nr(decoder);
16041618
decoder->timestamp_insn_cnt = 0;
1605-
decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
1619+
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
1620+
decoder->state.from_ip = decoder->ip;
1621+
decoder->ip = 0;
1622+
decoder->pge = false;
1623+
decoder->set_fup_tx_flags = false;
1624+
decoder->set_fup_ptw = false;
1625+
decoder->set_fup_mwait = false;
1626+
decoder->set_fup_pwre = false;
1627+
decoder->set_fup_exstop = false;
1628+
decoder->set_fup_bep = false;
16061629
decoder->overflow = true;
16071630
return -EOVERFLOW;
16081631
}
@@ -2957,6 +2980,7 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
29572980

29582981
case INTEL_PT_TIP_PGE: {
29592982
decoder->pge = true;
2983+
decoder->overflow = false;
29602984
intel_pt_mtc_cyc_cnt_pge(decoder);
29612985
intel_pt_set_nr(decoder);
29622986
if (decoder->packet.count == 0) {
@@ -3462,10 +3486,10 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder)
34623486
decoder->set_fup_pwre = false;
34633487
decoder->set_fup_exstop = false;
34643488
decoder->set_fup_bep = false;
3489+
decoder->overflow = false;
34653490

34663491
if (!decoder->branch_enable) {
34673492
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
3468-
decoder->overflow = false;
34693493
decoder->state.type = 0; /* Do not have a sample */
34703494
return 0;
34713495
}
@@ -3480,7 +3504,6 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder)
34803504
decoder->pkt_state = INTEL_PT_STATE_RESAMPLE;
34813505
else
34823506
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
3483-
decoder->overflow = false;
34843507

34853508
decoder->state.from_ip = 0;
34863509
decoder->state.to_ip = decoder->ip;
@@ -3699,7 +3722,8 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
36993722

37003723
if (err) {
37013724
decoder->state.err = intel_pt_ext_err(err);
3702-
decoder->state.from_ip = decoder->ip;
3725+
if (err != -EOVERFLOW)
3726+
decoder->state.from_ip = decoder->ip;
37033727
intel_pt_update_sample_time(decoder);
37043728
decoder->sample_tot_cyc_cnt = decoder->tot_cyc_cnt;
37053729
intel_pt_set_nr(decoder);

0 commit comments

Comments
 (0)