Skip to content

Commit

Permalink
perf intel-pt: Fix state setting when receiving overflow (OVF) packet
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
ahunter6 authored and acmel committed Dec 11, 2021
1 parent 4c761d8 commit c79ee2b
Showing 1 changed file with 28 additions and 4 deletions.
32 changes: 28 additions & 4 deletions tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,20 @@ static bool intel_pt_fup_event(struct intel_pt_decoder *decoder)
decoder->state.type |= INTEL_PT_BLK_ITEMS;
ret = true;
}
if (decoder->overflow) {
decoder->overflow = false;
if (!ret && !decoder->pge) {
if (decoder->hop) {
decoder->state.type = 0;
decoder->pkt_state = INTEL_PT_STATE_RESAMPLE;
}
decoder->pge = true;
decoder->state.type |= INTEL_PT_BRANCH | INTEL_PT_TRACE_BEGIN;
decoder->state.from_ip = 0;
decoder->state.to_ip = decoder->ip;
return true;
}
}
if (ret) {
decoder->state.from_ip = decoder->ip;
decoder->state.to_ip = 0;
Expand Down Expand Up @@ -1602,7 +1616,16 @@ static int intel_pt_overflow(struct intel_pt_decoder *decoder)
intel_pt_clear_tx_flags(decoder);
intel_pt_set_nr(decoder);
decoder->timestamp_insn_cnt = 0;
decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
decoder->state.from_ip = decoder->ip;
decoder->ip = 0;
decoder->pge = false;
decoder->set_fup_tx_flags = false;
decoder->set_fup_ptw = false;
decoder->set_fup_mwait = false;
decoder->set_fup_pwre = false;
decoder->set_fup_exstop = false;
decoder->set_fup_bep = false;
decoder->overflow = true;
return -EOVERFLOW;
}
Expand Down Expand Up @@ -2957,6 +2980,7 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)

case INTEL_PT_TIP_PGE: {
decoder->pge = true;
decoder->overflow = false;
intel_pt_mtc_cyc_cnt_pge(decoder);
intel_pt_set_nr(decoder);
if (decoder->packet.count == 0) {
Expand Down Expand Up @@ -3462,10 +3486,10 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder)
decoder->set_fup_pwre = false;
decoder->set_fup_exstop = false;
decoder->set_fup_bep = false;
decoder->overflow = false;

if (!decoder->branch_enable) {
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
decoder->overflow = false;
decoder->state.type = 0; /* Do not have a sample */
return 0;
}
Expand All @@ -3480,7 +3504,6 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder)
decoder->pkt_state = INTEL_PT_STATE_RESAMPLE;
else
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
decoder->overflow = false;

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

if (err) {
decoder->state.err = intel_pt_ext_err(err);
decoder->state.from_ip = decoder->ip;
if (err != -EOVERFLOW)
decoder->state.from_ip = decoder->ip;
intel_pt_update_sample_time(decoder);
decoder->sample_tot_cyc_cnt = decoder->tot_cyc_cnt;
intel_pt_set_nr(decoder);
Expand Down

0 comments on commit c79ee2b

Please sign in to comment.