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

Commit faaa8768 authored by Andi Kleen's avatar Andi Kleen Committed by Arnaldo Carvalho de Melo
Browse files

perf intel-pt/bts: Report instruction bytes and length in sample



Change Intel PT and BTS to pass up the length and the instruction
bytes of the decoded or sampled instruction in the perf sample.

The decoder already knows this information, we just need to pass it
up. Since it is only a couple of movs it is not very expensive.

Handle instruction cache too. Make sure ilen is always initialized.

Used in the next patch.

[Adrian: re-base on top (and adjust for) instruction buffer size tidy-up]
[Adrian: add BTS support and adjust commit message accordingly]

Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Link: http://lkml.kernel.org/r/1475847747-30994-3-git-send-email-adrian.hunter@intel.com


Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 32f98aab
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -177,6 +177,8 @@ enum {
	PERF_IP_FLAG_TRACE_BEGIN	|\
	PERF_IP_FLAG_TRACE_END)

#define MAX_INSN 16

struct perf_sample {
	u64 ip;
	u32 pid, tid;
@@ -193,6 +195,7 @@ struct perf_sample {
	u32 flags;
	u16 insn_len;
	u8  cpumode;
	char insn[MAX_INSN];
	void *raw_data;
	struct ip_callchain *callchain;
	struct branch_stack *branch_stack;
+1 −0
Original line number Diff line number Diff line
@@ -295,6 +295,7 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
	sample.cpu = btsq->cpu;
	sample.flags = btsq->sample_flags;
	sample.insn_len = btsq->intel_pt_insn.length;
	memcpy(sample.insn, btsq->intel_pt_insn.buf, INTEL_PT_INSN_BUF_SZ);

	if (bts->synth_opts.inject) {
		event.sample.header.size = bts->branches_event_size;
+2 −0
Original line number Diff line number Diff line
@@ -980,6 +980,8 @@ static int intel_pt_walk_insn(struct intel_pt_decoder *decoder,
out_no_progress:
	decoder->state.insn_op = intel_pt_insn->op;
	decoder->state.insn_len = intel_pt_insn->length;
	memcpy(decoder->state.insn, intel_pt_insn->buf,
	       INTEL_PT_INSN_BUF_SZ);

	if (decoder->tx_flags & INTEL_PT_IN_TX)
		decoder->state.flags |= INTEL_PT_IN_TX;
+1 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ struct intel_pt_state {
	uint32_t flags;
	enum intel_pt_insn_op insn_op;
	int insn_len;
	char insn[INTEL_PT_INSN_BUF_SZ];
};

struct intel_pt_insn;
+1 −1
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@

#include "intel-pt-insn-decoder.h"

#if INTEL_PT_INSN_BUF_SZ < MAX_INSN_SIZE
#if INTEL_PT_INSN_BUF_SZ < MAX_INSN_SIZE || INTEL_PT_INSN_BUF_SZ > MAX_INSN
#error Instruction buffer size too small
#endif

Loading