Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d4f0eda authored by Adrian Hunter's avatar Adrian Hunter Committed by Arnaldo Carvalho de Melo
Browse files

perf intel-pt/bts: Calculate cpumode for synthesized samples



In the absence of a fallback, samples must provide a correct cpumode for
the 'ip'. Do that now there is no fallback.

Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Reviewed-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: stable@vger.kernel.org # 4.19
Link: http://lkml.kernel.org/r/20181031091043.23465-6-adrian.hunter@intel.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 24248306
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -269,6 +269,13 @@ static int intel_bts_do_fix_overlap(struct auxtrace_queue *queue,
	return 0;
}

static inline u8 intel_bts_cpumode(struct intel_bts *bts, uint64_t ip)
{
	return machine__kernel_ip(bts->machine, ip) ?
	       PERF_RECORD_MISC_KERNEL :
	       PERF_RECORD_MISC_USER;
}

static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
					 struct branch *branch)
{
@@ -281,12 +288,8 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
	    bts->num_events++ <= bts->synth_opts.initial_skip)
		return 0;

	event.sample.header.type = PERF_RECORD_SAMPLE;
	event.sample.header.misc = PERF_RECORD_MISC_USER;
	event.sample.header.size = sizeof(struct perf_event_header);

	sample.cpumode = PERF_RECORD_MISC_USER;
	sample.ip = le64_to_cpu(branch->from);
	sample.cpumode = intel_bts_cpumode(bts, sample.ip);
	sample.pid = btsq->pid;
	sample.tid = btsq->tid;
	sample.addr = le64_to_cpu(branch->to);
@@ -298,6 +301,10 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
	sample.insn_len = btsq->intel_pt_insn.length;
	memcpy(sample.insn, btsq->intel_pt_insn.buf, INTEL_PT_INSN_BUF_SZ);

	event.sample.header.type = PERF_RECORD_SAMPLE;
	event.sample.header.misc = sample.cpumode;
	event.sample.header.size = sizeof(struct perf_event_header);

	if (bts->synth_opts.inject) {
		event.sample.header.size = bts->branches_event_size;
		ret = perf_event__synthesize_sample(&event,
+13 −9
Original line number Diff line number Diff line
@@ -407,6 +407,13 @@ intel_pt_cache_lookup(struct dso *dso, struct machine *machine, u64 offset)
	return auxtrace_cache__lookup(dso->auxtrace_cache, offset);
}

static inline u8 intel_pt_cpumode(struct intel_pt *pt, uint64_t ip)
{
	return ip >= pt->kernel_start ?
	       PERF_RECORD_MISC_KERNEL :
	       PERF_RECORD_MISC_USER;
}

static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
				   uint64_t *insn_cnt_ptr, uint64_t *ip,
				   uint64_t to_ip, uint64_t max_insn_cnt,
@@ -429,10 +436,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
	if (to_ip && *ip == to_ip)
		goto out_no_cache;

	if (*ip >= ptq->pt->kernel_start)
		cpumode = PERF_RECORD_MISC_KERNEL;
	else
		cpumode = PERF_RECORD_MISC_USER;
	cpumode = intel_pt_cpumode(ptq->pt, *ip);

	thread = ptq->thread;
	if (!thread) {
@@ -1059,15 +1063,11 @@ static void intel_pt_prep_b_sample(struct intel_pt *pt,
				   union perf_event *event,
				   struct perf_sample *sample)
{
	event->sample.header.type = PERF_RECORD_SAMPLE;
	event->sample.header.misc = PERF_RECORD_MISC_USER;
	event->sample.header.size = sizeof(struct perf_event_header);

	if (!pt->timeless_decoding)
		sample->time = tsc_to_perf_time(ptq->timestamp, &pt->tc);

	sample->cpumode = PERF_RECORD_MISC_USER;
	sample->ip = ptq->state->from_ip;
	sample->cpumode = intel_pt_cpumode(pt, sample->ip);
	sample->pid = ptq->pid;
	sample->tid = ptq->tid;
	sample->addr = ptq->state->to_ip;
@@ -1076,6 +1076,10 @@ static void intel_pt_prep_b_sample(struct intel_pt *pt,
	sample->flags = ptq->flags;
	sample->insn_len = ptq->insn_len;
	memcpy(sample->insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);

	event->sample.header.type = PERF_RECORD_SAMPLE;
	event->sample.header.misc = sample->cpumode;
	event->sample.header.size = sizeof(struct perf_event_header);
}

static int intel_pt_inject_event(union perf_event *event,