mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Adrian Hunter <adrian.hunter@intel.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>,
	linux-kernel@vger.kernel.org, Jiri Olsa <jolsa@redhat.com>
Subject: [PATCH V6 13/17] perf tools: Output sample flags and insn_len from intel_bts
Date: Fri, 29 May 2015 16:33:41 +0300	[thread overview]
Message-ID: <1432906425-9911-14-git-send-email-adrian.hunter@intel.com> (raw)
In-Reply-To: <1432906425-9911-1-git-send-email-adrian.hunter@intel.com>

intel_bts synthesizes samples.  Fill in the new flags and insn_len
members with instruction information.

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

diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index 48bcbd6..b068860 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -30,6 +30,7 @@
 #include "debug.h"
 #include "tsc.h"
 #include "auxtrace.h"
+#include "intel-pt-decoder/intel-pt-insn-decoder.h"
 #include "intel-bts.h"
 
 #define MAX_TIMESTAMP (~0ULL)
@@ -58,6 +59,7 @@ struct intel_bts {
 	bool				cap_user_time_zero;
 	struct itrace_synth_opts	synth_opts;
 	bool				sample_branches;
+	u32				branches_filter;
 	u64				branches_sample_type;
 	u64				branches_id;
 	size_t				branches_event_size;
@@ -74,6 +76,8 @@ struct intel_bts_queue {
 	pid_t			tid;
 	int			cpu;
 	u64			time;
+	struct intel_pt_insn	intel_pt_insn;
+	u32			sample_flags;
 };
 
 struct branch {
@@ -281,6 +285,8 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
 	sample.stream_id = btsq->bts->branches_id;
 	sample.period = 1;
 	sample.cpu = btsq->cpu;
+	sample.flags = btsq->sample_flags;
+	sample.insn_len = btsq->intel_pt_insn.length;
 
 	if (bts->synth_opts.inject) {
 		event.sample.header.size = bts->branches_event_size;
@@ -300,11 +306,115 @@ static int intel_bts_synth_branch_sample(struct intel_bts_queue *btsq,
 	return ret;
 }
 
+static int intel_bts_get_next_insn(struct intel_bts_queue *btsq, u64 ip)
+{
+	struct machine *machine = btsq->bts->machine;
+	struct thread *thread;
+	struct addr_location al;
+	unsigned char buf[1024];
+	size_t bufsz;
+	ssize_t len;
+	int x86_64;
+	uint8_t cpumode;
+
+	bufsz = intel_pt_insn_max_size();
+
+	if (machine__kernel_ip(machine, ip))
+		cpumode = PERF_RECORD_MISC_KERNEL;
+	else
+		cpumode = PERF_RECORD_MISC_USER;
+
+	thread = machine__find_thread(machine, -1, btsq->tid);
+	if (!thread)
+		return -1;
+
+	thread__find_addr_map(thread, cpumode, MAP__FUNCTION, ip, &al);
+	if (!al.map || !al.map->dso)
+		return -1;
+
+	len = dso__data_read_addr(al.map->dso, al.map, machine, ip, buf, bufsz);
+	if (len <= 0)
+		return -1;
+
+	/* Load maps to ensure dso->is_64_bit has been updated */
+	map__load(al.map, machine->symbol_filter);
+
+	x86_64 = al.map->dso->is_64_bit;
+
+	if (intel_pt_get_insn(buf, len, x86_64, &btsq->intel_pt_insn))
+		return -1;
+
+	return 0;
+}
+
+static int intel_bts_synth_error(struct intel_bts *bts, int cpu, pid_t pid,
+				 pid_t tid, u64 ip)
+{
+	union perf_event event;
+	int err;
+
+	auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE,
+			     INTEL_BTS_ERR_NOINSN, cpu, pid, tid, ip,
+			     "Failed to get instruction");
+
+	err = perf_session__deliver_synth_event(bts->session, &event, NULL);
+	if (err)
+		pr_err("Intel BTS: failed to deliver error event, error %d\n",
+		       err);
+
+	return err;
+}
+
+static int intel_bts_get_branch_type(struct intel_bts_queue *btsq,
+				     struct branch *branch)
+{
+	int err;
+
+	if (!branch->from) {
+		if (branch->to)
+			btsq->sample_flags = PERF_IP_FLAG_BRANCH |
+					     PERF_IP_FLAG_TRACE_BEGIN;
+		else
+			btsq->sample_flags = 0;
+		btsq->intel_pt_insn.length = 0;
+	} else if (!branch->to) {
+		btsq->sample_flags = PERF_IP_FLAG_BRANCH |
+				     PERF_IP_FLAG_TRACE_END;
+		btsq->intel_pt_insn.length = 0;
+	} else {
+		err = intel_bts_get_next_insn(btsq, branch->from);
+		if (err) {
+			btsq->sample_flags = 0;
+			btsq->intel_pt_insn.length = 0;
+			if (!btsq->bts->synth_opts.errors)
+				return 0;
+			err = intel_bts_synth_error(btsq->bts, btsq->cpu,
+						    btsq->pid, btsq->tid,
+						    branch->from);
+			return err;
+		}
+		btsq->sample_flags = intel_pt_insn_type(btsq->intel_pt_insn.op);
+		/* Check for an async branch into the kernel */
+		if (!machine__kernel_ip(btsq->bts->machine, branch->from) &&
+		    machine__kernel_ip(btsq->bts->machine, branch->to) &&
+		    btsq->sample_flags != (PERF_IP_FLAG_BRANCH |
+					   PERF_IP_FLAG_CALL |
+					   PERF_IP_FLAG_SYSCALLRET))
+			btsq->sample_flags = PERF_IP_FLAG_BRANCH |
+					     PERF_IP_FLAG_CALL |
+					     PERF_IP_FLAG_ASYNC |
+					     PERF_IP_FLAG_INTERRUPT;
+	}
+
+	return 0;
+}
+
 static int intel_bts_process_buffer(struct intel_bts_queue *btsq,
 				    struct auxtrace_buffer *buffer)
 {
 	struct branch *branch;
-	size_t sz;
+	size_t sz, bsz = sizeof(struct branch);
+	u32 filter = btsq->bts->branches_filter;
 	int err = 0;
 
 	if (buffer->use_data) {
@@ -318,14 +428,15 @@ static int intel_bts_process_buffer(struct intel_bts_queue *btsq,
 	if (!btsq->bts->sample_branches)
 		return 0;
 
-	while (sz > sizeof(struct branch)) {
+	for (; sz > bsz; branch += 1, sz -= bsz) {
 		if (!branch->from && !branch->to)
 			continue;
+		intel_bts_get_branch_type(btsq, branch);
+		if (filter && !(filter & btsq->sample_flags))
+			continue;
 		err = intel_bts_synth_branch_sample(btsq, branch);
 		if (err)
 			break;
-		branch += 1;
-		sz -= sizeof(struct branch);
 	}
 	return err;
 }
@@ -771,6 +882,13 @@ int intel_bts_process_auxtrace_info(union perf_event *event,
 	else
 		itrace_synth_opts__set_default(&bts->synth_opts);
 
+	if (bts->synth_opts.calls)
+		bts->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC |
+					PERF_IP_FLAG_TRACE_END;
+	if (bts->synth_opts.returns)
+		bts->branches_filter |= PERF_IP_FLAG_RETURN |
+					PERF_IP_FLAG_TRACE_BEGIN;
+
 	err = intel_bts_synth_events(bts, session);
 	if (err)
 		goto err_free_queues;
-- 
1.9.1


  parent reply	other threads:[~2015-05-29 13:39 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-29 13:33 [PATCH V6 00/17] perf tools: Introduce an abstraction for AUX Area and Instruction Tracing Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 01/17] perf db-export: Fix thread ref-counting Adrian Hunter
2015-05-29 18:35   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 02/17] perf tools: Ensure thread-stack is flushed Adrian Hunter
2015-06-18 21:56   ` Arnaldo Carvalho de Melo
2015-06-19  5:50     ` Adrian Hunter
2015-06-19 23:15   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 03/17] perf auxtrace: Add Intel PT as an AUX area tracing type Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 04/17] perf tools: Add Intel PT packet decoder Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 05/17] perf tools: Add Intel PT instruction decoder Adrian Hunter
2015-06-18 22:29   ` Arnaldo Carvalho de Melo
2015-06-19 15:44     ` Arnaldo Carvalho de Melo
2015-06-22 12:40       ` Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 06/17] perf tools: Add Intel PT log Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 07/17] perf tools: Add Intel PT decoder Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 08/17] perf tools: Add Intel PT support Adrian Hunter
2015-06-19 16:04   ` Arnaldo Carvalho de Melo
2015-06-19 16:22     ` Arnaldo Carvalho de Melo
2015-06-19 19:33     ` Adrian Hunter
2015-06-19 19:41       ` Arnaldo Carvalho de Melo
2015-06-22 18:24         ` Arnaldo Carvalho de Melo
2015-06-22 20:26           ` Adrian Hunter
2015-06-22 23:00             ` Arnaldo Carvalho de Melo
2015-06-23  6:29               ` Adrian Hunter
2015-06-23 15:15                 ` Arnaldo Carvalho de Melo
2015-06-25 13:37                   ` Adrian Hunter
2015-06-25 13:45                     ` Arnaldo Carvalho de Melo
2015-06-25 23:56                       ` Arnaldo Carvalho de Melo
2015-06-26  0:09                         ` Arnaldo Carvalho de Melo
2015-06-26  6:48                           ` Adrian Hunter
2015-06-26 13:41                             ` Arnaldo Carvalho de Melo
2015-06-26 13:47                               ` Adrian Hunter
2015-06-26 15:08                                 ` Arnaldo Carvalho de Melo
2015-06-26 20:34                             ` Arnaldo Carvalho de Melo
2015-05-29 13:33 ` [PATCH V6 09/17] perf tools: Take Intel PT into use Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 10/17] perf tools: Allow auxtrace data alignment Adrian Hunter
2015-06-25  7:58   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 11/17] perf tools: Add Intel BTS support Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 12/17] perf tools: Output sample flags and insn_len from intel_pt Adrian Hunter
2015-05-29 13:33 ` Adrian Hunter [this message]
2015-05-29 13:33 ` [PATCH V6 14/17] perf tools: Intel PT to always update thread stack trace number Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 15/17] perf tools: Intel BTS " Adrian Hunter
2015-06-19 16:11   ` Arnaldo Carvalho de Melo
2015-06-22 12:38     ` Adrian Hunter
2015-06-22 14:33       ` Arnaldo Carvalho de Melo
2015-05-29 13:33 ` [PATCH V6 16/17] perf tools: Put itrace options into an asciidoc include Adrian Hunter
2015-05-29 13:33 ` [PATCH V6 17/17] perf tools: Add example call-graph script Adrian Hunter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1432906425-9911-14-git-send-email-adrian.hunter@intel.com \
    --to=adrian.hunter@intel.com \
    --cc=acme@kernel.org \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®