mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] perf tools: A couple more Intel PT patches
@ 2015-06-10 12:42 Adrian Hunter
  2015-06-10 12:42 ` [PATCH 1/2] perf tools: Improve Intel PT sync to sideband events Adrian Hunter
  2015-06-10 12:42 ` [PATCH 2/2] perf tools: Fix Intel PT getting stuck in a loop Adrian Hunter
  0 siblings, 2 replies; 3+ messages in thread
From: Adrian Hunter @ 2015-06-10 12:42 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: linux-kernel, Jiri Olsa

Hi

Here are a couple more patches for Intel PT. They
apply on top of the patches already sent. The
whole lot can be found here:

	http://git.infradead.org/users/ahunter/linux-perf.git


Adrian Hunter (2):
      perf tools: Improve Intel PT sync to sideband events
      perf tools: Fix Intel PT getting stuck in a loop

 .../perf/util/intel-pt-decoder/intel-pt-decoder.c  | 42 ++++++++++++++++++++++
 .../perf/util/intel-pt-decoder/intel-pt-decoder.h  |  1 +
 tools/perf/util/intel-pt.c                         | 28 +++++++--------
 3 files changed, 57 insertions(+), 14 deletions(-)


Regards
Adrian

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] perf tools: Improve Intel PT sync to sideband events
  2015-06-10 12:42 [PATCH 0/2] perf tools: A couple more Intel PT patches Adrian Hunter
@ 2015-06-10 12:42 ` Adrian Hunter
  2015-06-10 12:42 ` [PATCH 2/2] perf tools: Fix Intel PT getting stuck in a loop Adrian Hunter
  1 sibling, 0 replies; 3+ messages in thread
From: Adrian Hunter @ 2015-06-10 12:42 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: linux-kernel, Jiri Olsa

To help synchronize trace data with sideband events
the timestamp when returning to userspace is estimated.

That was not always being done if switch information
was not available, but it is still useful for sync'ing
to mmap changes, so simplify by doing it always when
TSC is available.  Also add log prints to help debug
synchronization to sideband.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/util/intel-pt.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 5a59fd8e79ae..751c43a1fbcc 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -63,7 +63,6 @@ struct intel_pt {
 	bool data_queued;
 	bool est_tsc;
 	bool sync_switch;
-	bool est_tsc_orig;
 	int have_sched_switch;
 	u32 pmu_type;
 	u64 kernel_start;
@@ -1175,8 +1174,6 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp)
 				intel_pt_log("switch_ip: %"PRIx64" ptss_ip: %"PRIx64"\n",
 					     pt->switch_ip, pt->ptss_ip);
 				pt->sync_switch = true;
-				pt->est_tsc_orig = pt->est_tsc;
-				pt->est_tsc = false;
 			}
 		}
 	}
@@ -1195,7 +1192,6 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp)
 			if (pt->sync_switch &&
 			    state->from_ip >= pt->kernel_start) {
 				pt->sync_switch = false;
-				pt->est_tsc = pt->est_tsc_orig;
 				intel_pt_next_tid(pt, ptq);
 			}
 			if (pt->synth_opts.errors) {
@@ -1214,19 +1210,19 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp)
 		intel_pt_sample_flags(ptq);
 
 		/* Use estimated TSC upon return to user space */
-		if (pt->est_tsc) {
-			if (state->from_ip >= pt->kernel_start &&
-			    state->to_ip &&
-			    state->to_ip < pt->kernel_start)
-				ptq->timestamp = state->est_timestamp;
-			else if (state->timestamp > ptq->timestamp)
-				ptq->timestamp = state->timestamp;
+		if (pt->est_tsc &&
+		    (state->from_ip >= pt->kernel_start || !state->from_ip) &&
+		    state->to_ip && state->to_ip < pt->kernel_start) {
+			intel_pt_log("TSC %"PRIx64" est. TSC %"PRIx64"\n",
+				     state->timestamp, state->est_timestamp);
+			ptq->timestamp = state->est_timestamp;
 		/* Use estimated TSC in unknown switch state */
 		} else if (pt->sync_switch &&
 			   ptq->switch_state == INTEL_PT_SS_UNKNOWN &&
-			   state->to_ip == pt->switch_ip &&
-			   (ptq->flags & PERF_IP_FLAG_CALL) &&
+			   intel_pt_is_switch_ip(ptq, state->to_ip) &&
 			   ptq->next_tid == -1) {
+			intel_pt_log("TSC %"PRIx64" est. TSC %"PRIx64"\n",
+				     state->timestamp, state->est_timestamp);
 			ptq->timestamp = state->est_timestamp;
 		} else if (state->timestamp > ptq->timestamp) {
 			ptq->timestamp = state->timestamp;
@@ -1484,6 +1480,10 @@ static int intel_pt_process_event(struct perf_session *session,
 	else if (event->header.type == PERF_RECORD_ITRACE_START)
 		err = intel_pt_process_itrace_start(pt, event, sample);
 
+	intel_pt_log("event %s (%u): cpu %d time %"PRIu64" tsc %#"PRIx64"\n",
+		     perf_event__name(event->header.type), event->header.type,
+		     sample->cpu, sample->time, timestamp);
+
 	return err;
 }
 
@@ -1806,7 +1806,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
 	pt->timeless_decoding = intel_pt_timeless_decoding(pt);
 	pt->have_tsc = intel_pt_have_tsc(pt);
 	pt->sampling_mode = false;
-	pt->est_tsc = pt->per_cpu_mmaps && !pt->timeless_decoding;
+	pt->est_tsc = !pt->timeless_decoding;
 
 	pt->unknown_thread = thread__new(999999999, 999999999);
 	if (!pt->unknown_thread) {
-- 
1.9.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/2] perf tools: Fix Intel PT getting stuck in a loop
  2015-06-10 12:42 [PATCH 0/2] perf tools: A couple more Intel PT patches Adrian Hunter
  2015-06-10 12:42 ` [PATCH 1/2] perf tools: Improve Intel PT sync to sideband events Adrian Hunter
@ 2015-06-10 12:42 ` Adrian Hunter
  1 sibling, 0 replies; 3+ messages in thread
From: Adrian Hunter @ 2015-06-10 12:42 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: linux-kernel, Jiri Olsa

Check for being stuck in a loop.  That can happen if a
decoder error results in the decoder erroneously setting
the ip to an address that is itself in an infinite loop
that consumes no packets.  The only way to be in a loop
that consumes no packets is if it consists of unconditional
branches.  So the check for being stuck is if we see
a repeating cycle of consecutive unconditional branches.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 .../perf/util/intel-pt-decoder/intel-pt-decoder.c  | 42 ++++++++++++++++++++++
 .../perf/util/intel-pt-decoder/intel-pt-decoder.h  |  1 +
 2 files changed, 43 insertions(+)

diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 748a7a078313..e8ff6573ecec 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -37,6 +37,9 @@
 
 #define INTEL_PT_RETURN 1
 
+/* Maximum number of loops with no packets consumed i.e. stuck in a loop */
+#define INTEL_PT_MAX_LOOPS 10000
+
 struct intel_pt_blk {
 	struct intel_pt_blk *prev;
 	uint64_t ip[INTEL_PT_BLK_SIZE];
@@ -114,6 +117,10 @@ struct intel_pt_decoder {
 	unsigned int fup_tx_flags;
 	unsigned int tx_flags;
 	uint64_t timestamp_insn_cnt;
+	uint64_t stuck_ip;
+	int no_progress;
+	int stuck_ip_prd;
+	int stuck_ip_cnt;
 	const unsigned char *next_buf;
 	size_t next_len;
 	unsigned char temp_buf[INTEL_PT_PKT_MAX_SZ];
@@ -263,6 +270,8 @@ static int intel_pt_ext_err(int code)
 		return INTEL_PT_ERR_OVR;
 	case -ENOSPC:
 		return INTEL_PT_ERR_LOST;
+	case -ELOOP:
+		return INTEL_PT_ERR_NELOOP;
 	default:
 		return INTEL_PT_ERR_UNK;
 	}
@@ -278,6 +287,7 @@ static const char *intel_pt_err_msgs[] = {
 	[INTEL_PT_ERR_OVR]    = "Overflow packet",
 	[INTEL_PT_ERR_LOST]   = "Lost trace data",
 	[INTEL_PT_ERR_UNK]    = "Unknown error!",
+	[INTEL_PT_ERR_NELOOP] = "Never-ending loop",
 };
 
 int intel_pt__strerror(int code, char *buf, size_t buflen)
@@ -550,6 +560,7 @@ static int intel_pt_walk_insn(struct intel_pt_decoder *decoder,
 	decoder->period_insn_cnt += insn_cnt;
 
 	if (err) {
+		decoder->no_progress = 0;
 		decoder->pkt_state = INTEL_PT_STATE_ERR2;
 		intel_pt_log_at("ERROR: Failed to get instruction",
 				decoder->ip);
@@ -589,13 +600,44 @@ static int intel_pt_walk_insn(struct intel_pt_decoder *decoder,
 	}
 
 	if (intel_pt_insn->branch == INTEL_PT_BR_UNCONDITIONAL) {
+		int cnt = decoder->no_progress++;
+
 		decoder->state.from_ip = decoder->ip;
 		decoder->ip += intel_pt_insn->length +
 				intel_pt_insn->rel;
 		decoder->state.to_ip = decoder->ip;
 		err = INTEL_PT_RETURN;
+
+		/*
+		 * Check for being stuck in a loop.  This can happen if a
+		 * decoder error results in the decoder erroneously setting the
+		 * ip to an address that is itself in an infinite loop that
+		 * consumes no packets.  When that happens, there must be an
+		 * unconditional branch.
+		 */
+		if (cnt) {
+			if (cnt == 1) {
+				decoder->stuck_ip = decoder->state.to_ip;
+				decoder->stuck_ip_prd = 1;
+				decoder->stuck_ip_cnt = 1;
+			} else if (cnt > INTEL_PT_MAX_LOOPS ||
+				   decoder->state.to_ip == decoder->stuck_ip) {
+				intel_pt_log_at("ERROR: Never-ending loop",
+						decoder->state.to_ip);
+				decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
+				err = -ELOOP;
+				goto out;
+			} else if (!--decoder->stuck_ip_cnt) {
+				decoder->stuck_ip_prd += 1;
+				decoder->stuck_ip_cnt = decoder->stuck_ip_prd;
+				decoder->stuck_ip = decoder->state.to_ip;
+			}
+		}
+		goto out_no_progress;
 	}
 out:
+	decoder->no_progress = 0;
+out_no_progress:
 	decoder->state.insn_op = intel_pt_insn->op;
 	decoder->state.insn_len = intel_pt_insn->length;
 
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
index 955263adfd8d..706c6bccc57e 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
@@ -48,6 +48,7 @@ enum {
 	INTEL_PT_ERR_OVR,
 	INTEL_PT_ERR_LOST,
 	INTEL_PT_ERR_UNK,
+	INTEL_PT_ERR_NELOOP,
 	INTEL_PT_ERR_MAX,
 };
 
-- 
1.9.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-06-10 12:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-10 12:42 [PATCH 0/2] perf tools: A couple more Intel PT patches Adrian Hunter
2015-06-10 12:42 ` [PATCH 1/2] perf tools: Improve Intel PT sync to sideband events Adrian Hunter
2015-06-10 12:42 ` [PATCH 2/2] perf tools: Fix Intel PT getting stuck in a loop Adrian Hunter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome