[PATCH 1/2] perf tools: Improve Intel PT sync to sideband events

From: Adrian Hunter
Date: Wed Jun 10 2015 - 08:51:30 EST


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@xxxxxxxxx>
---
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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/