perf intel-pt: Fix FUP packet state
authorAdrian Hunter <adrian.hunter@intel.com>
Fri, 10 Jul 2020 15:10:53 +0000 (18:10 +0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 6 Aug 2020 11:17:24 +0000 (08:17 -0300)
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>
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c

index f8ccfd6..75c4bd7 100644 (file)
@@ -1164,6 +1164,7 @@ static int intel_pt_walk_fup(struct intel_pt_decoder *decoder)
                        return 0;
                if (err == -EAGAIN ||
                    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))
                                return 0;
                        return -EAGAIN;
@@ -1942,17 +1943,13 @@ next:
                        }
                        if (decoder->set_fup_mwait)
                                no_tip = true;
+                       if (no_tip)
+                               decoder->pkt_state = INTEL_PT_STATE_FUP_NO_TIP;
+                       else
+                               decoder->pkt_state = INTEL_PT_STATE_FUP;
                        err = intel_pt_walk_fup(decoder);
-                       if (err != -EAGAIN) {
-                               if (err)
-                                       return err;
-                               if (no_tip)
-                                       decoder->pkt_state =
-                                               INTEL_PT_STATE_FUP_NO_TIP;
-                               else
-                                       decoder->pkt_state = INTEL_PT_STATE_FUP;
-                               return 0;
-                       }
+                       if (err != -EAGAIN)
+                               return err;
                        if (no_tip) {
                                no_tip = false;
                                break;
@@ -2599,15 +2596,11 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
                        err = intel_pt_walk_tip(decoder);
                        break;
                case INTEL_PT_STATE_FUP:
-                       decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
                        err = intel_pt_walk_fup(decoder);
                        if (err == -EAGAIN)
                                err = intel_pt_walk_fup_tip(decoder);
-                       else if (!err)
-                               decoder->pkt_state = INTEL_PT_STATE_FUP;
                        break;
                case INTEL_PT_STATE_FUP_NO_TIP:
-                       decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
                        err = intel_pt_walk_fup(decoder);
                        if (err == -EAGAIN)
                                err = intel_pt_walk_trace(decoder);