perf intel-pt: Fix FUP packet state

commit 401136bb08 upstream.

While walking code towards a FUP ip, the packet state is
INTEL_PT_STATE_FUP or INTEL_PT_STATE_FUP_NO_TIP. That was mishandled
resulting in the state becoming INTEL_PT_STATE_IN_SYNC prematurely.  The
result was an occasional lost EXSTOP event.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: stable@vger.kernel.org
Link: http://lore.kernel.org/lkml/20200710151104.15137-2-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Adrian Hunter 2020-07-10 18:10:53 +03:00 committed by Greg Kroah-Hartman
parent 169015f464
commit 8214e74b66
1 changed files with 7 additions and 14 deletions

View File

@ -1164,6 +1164,7 @@ static int intel_pt_walk_fup(struct intel_pt_decoder *decoder)
return 0; return 0;
if (err == -EAGAIN || if (err == -EAGAIN ||
intel_pt_fup_with_nlip(decoder, &intel_pt_insn, ip, err)) { intel_pt_fup_with_nlip(decoder, &intel_pt_insn, ip, err)) {
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
if (intel_pt_fup_event(decoder)) if (intel_pt_fup_event(decoder))
return 0; return 0;
return -EAGAIN; return -EAGAIN;
@ -1942,17 +1943,13 @@ next:
} }
if (decoder->set_fup_mwait) if (decoder->set_fup_mwait)
no_tip = true; no_tip = true;
err = intel_pt_walk_fup(decoder);
if (err != -EAGAIN) {
if (err)
return err;
if (no_tip) if (no_tip)
decoder->pkt_state = decoder->pkt_state = INTEL_PT_STATE_FUP_NO_TIP;
INTEL_PT_STATE_FUP_NO_TIP;
else else
decoder->pkt_state = INTEL_PT_STATE_FUP; decoder->pkt_state = INTEL_PT_STATE_FUP;
return 0; err = intel_pt_walk_fup(decoder);
} if (err != -EAGAIN)
return err;
if (no_tip) { if (no_tip) {
no_tip = false; no_tip = false;
break; break;
@ -2599,15 +2596,11 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
err = intel_pt_walk_tip(decoder); err = intel_pt_walk_tip(decoder);
break; break;
case INTEL_PT_STATE_FUP: case INTEL_PT_STATE_FUP:
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
err = intel_pt_walk_fup(decoder); err = intel_pt_walk_fup(decoder);
if (err == -EAGAIN) if (err == -EAGAIN)
err = intel_pt_walk_fup_tip(decoder); err = intel_pt_walk_fup_tip(decoder);
else if (!err)
decoder->pkt_state = INTEL_PT_STATE_FUP;
break; break;
case INTEL_PT_STATE_FUP_NO_TIP: case INTEL_PT_STATE_FUP_NO_TIP:
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
err = intel_pt_walk_fup(decoder); err = intel_pt_walk_fup(decoder);
if (err == -EAGAIN) if (err == -EAGAIN)
err = intel_pt_walk_trace(decoder); err = intel_pt_walk_trace(decoder);