All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org,
	Adrian Hunter <adrian.hunter@intel.com>,
	Andi Kleen <ak@linux.intel.com>,
	Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 19/30] perf intel-pt: Factor out common code synthesizing event samples
Date: Fri, 30 Jun 2017 19:25:03 -0300	[thread overview]
Message-ID: <20170630222514.11832-20-acme@kernel.org> (raw)
In-Reply-To: <20170630222514.11832-1-acme@kernel.org>

From: Adrian Hunter <adrian.hunter@intel.com>

Factor out common code in functions synthesizing event samples i.e.
intel_pt_synth_branch_sample(), intel_pt_synth_instruction_sample() and
intel_pt_synth_transaction_sample().

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Link: http://lkml.kernel.org/r/1495786658-18063-27-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/intel-pt.c | 222 ++++++++++++++++++++-------------------------
 1 file changed, 100 insertions(+), 122 deletions(-)

diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 6df836469f2b..dbff5dca09f0 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -1058,6 +1058,36 @@ static void intel_pt_update_last_branch_rb(struct intel_pt_queue *ptq)
 		bs->nr += 1;
 }
 
+static inline bool intel_pt_skip_event(struct intel_pt *pt)
+{
+	return pt->synth_opts.initial_skip &&
+	       pt->num_events++ < pt->synth_opts.initial_skip;
+}
+
+static void intel_pt_prep_b_sample(struct intel_pt *pt,
+				   struct intel_pt_queue *ptq,
+				   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->pid = ptq->pid;
+	sample->tid = ptq->tid;
+	sample->addr = ptq->state->to_ip;
+	sample->period = 1;
+	sample->cpu = ptq->cpu;
+	sample->flags = ptq->flags;
+	sample->insn_len = ptq->insn_len;
+	memcpy(sample->insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
+}
+
 static int intel_pt_inject_event(union perf_event *event,
 				 struct perf_sample *sample, u64 type,
 				 bool swapped)
@@ -1066,9 +1096,35 @@ static int intel_pt_inject_event(union perf_event *event,
 	return perf_event__synthesize_sample(event, type, 0, sample, swapped);
 }
 
-static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
+static inline int intel_pt_opt_inject(struct intel_pt *pt,
+				      union perf_event *event,
+				      struct perf_sample *sample, u64 type)
+{
+	if (!pt->synth_opts.inject)
+		return 0;
+
+	return intel_pt_inject_event(event, sample, type, pt->synth_needs_swap);
+}
+
+static int intel_pt_deliver_synth_b_event(struct intel_pt *pt,
+					  union perf_event *event,
+					  struct perf_sample *sample, u64 type)
 {
 	int ret;
+
+	ret = intel_pt_opt_inject(pt, event, sample, type);
+	if (ret)
+		return ret;
+
+	ret = perf_session__deliver_synth_event(pt->session, event, sample);
+	if (ret)
+		pr_err("Intel PT: failed to deliver event, error %d\n", ret);
+
+	return ret;
+}
+
+static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
+{
 	struct intel_pt *pt = ptq->pt;
 	union perf_event *event = ptq->event_buf;
 	struct perf_sample sample = { .ip = 0, };
@@ -1080,29 +1136,13 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
 	if (pt->branches_filter && !(pt->branches_filter & ptq->flags))
 		return 0;
 
-	if (pt->synth_opts.initial_skip &&
-	    pt->num_events++ < pt->synth_opts.initial_skip)
+	if (intel_pt_skip_event(pt))
 		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);
+	intel_pt_prep_b_sample(pt, ptq, event, &sample);
 
-	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.pid = ptq->pid;
-	sample.tid = ptq->tid;
-	sample.addr = ptq->state->to_ip;
 	sample.id = ptq->pt->branches_id;
 	sample.stream_id = ptq->pt->branches_id;
-	sample.period = 1;
-	sample.cpu = ptq->cpu;
-	sample.flags = ptq->flags;
-	sample.insn_len = ptq->insn_len;
-	memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
 
 	/*
 	 * perf report cannot handle events without a branch stack when using
@@ -1119,78 +1159,38 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
 		sample.branch_stack = (struct branch_stack *)&dummy_bs;
 	}
 
-	if (pt->synth_opts.inject) {
-		ret = intel_pt_inject_event(event, &sample,
-					    pt->branches_sample_type,
-					    pt->synth_needs_swap);
-		if (ret)
-			return ret;
-	}
-
-	ret = perf_session__deliver_synth_event(pt->session, event, &sample);
-	if (ret)
-		pr_err("Intel Processor Trace: failed to deliver branch event, error %d\n",
-		       ret);
-
-	return ret;
+	return intel_pt_deliver_synth_b_event(pt, event, &sample,
+					      pt->branches_sample_type);
 }
 
-static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
+static void intel_pt_prep_sample(struct intel_pt *pt,
+				 struct intel_pt_queue *ptq,
+				 union perf_event *event,
+				 struct perf_sample *sample)
 {
-	int ret;
-	struct intel_pt *pt = ptq->pt;
-	union perf_event *event = ptq->event_buf;
-	struct perf_sample sample = { .ip = 0, };
-
-	if (pt->synth_opts.initial_skip &&
-	    pt->num_events++ < pt->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);
-
-	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.pid = ptq->pid;
-	sample.tid = ptq->tid;
-	sample.addr = ptq->state->to_ip;
-	sample.id = ptq->pt->instructions_id;
-	sample.stream_id = ptq->pt->instructions_id;
-	sample.period = ptq->state->tot_insn_cnt - ptq->last_insn_cnt;
-	sample.cpu = ptq->cpu;
-	sample.flags = ptq->flags;
-	sample.insn_len = ptq->insn_len;
-	memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
-
-	ptq->last_insn_cnt = ptq->state->tot_insn_cnt;
+	intel_pt_prep_b_sample(pt, ptq, event, sample);
 
 	if (pt->synth_opts.callchain) {
 		thread_stack__sample(ptq->thread, ptq->chain,
-				     pt->synth_opts.callchain_sz, sample.ip);
-		sample.callchain = ptq->chain;
+				     pt->synth_opts.callchain_sz, sample->ip);
+		sample->callchain = ptq->chain;
 	}
 
 	if (pt->synth_opts.last_branch) {
 		intel_pt_copy_last_branch_rb(ptq);
-		sample.branch_stack = ptq->last_branch;
+		sample->branch_stack = ptq->last_branch;
 	}
+}
 
-	if (pt->synth_opts.inject) {
-		ret = intel_pt_inject_event(event, &sample,
-					    pt->instructions_sample_type,
-					    pt->synth_needs_swap);
-		if (ret)
-			return ret;
-	}
+static inline int intel_pt_deliver_synth_event(struct intel_pt *pt,
+					       struct intel_pt_queue *ptq,
+					       union perf_event *event,
+					       struct perf_sample *sample,
+					       u64 type)
+{
+	int ret;
 
-	ret = perf_session__deliver_synth_event(pt->session, event, &sample);
-	if (ret)
-		pr_err("Intel Processor Trace: failed to deliver instruction event, error %d\n",
-		       ret);
+	ret = intel_pt_deliver_synth_b_event(pt, event, sample, type);
 
 	if (pt->synth_opts.last_branch)
 		intel_pt_reset_last_branch_rb(ptq);
@@ -1198,65 +1198,43 @@ static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
 	return ret;
 }
 
-static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq)
+static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
 {
-	int ret;
 	struct intel_pt *pt = ptq->pt;
 	union perf_event *event = ptq->event_buf;
 	struct perf_sample sample = { .ip = 0, };
 
-	if (pt->synth_opts.initial_skip &&
-	    pt->num_events++ < pt->synth_opts.initial_skip)
+	if (intel_pt_skip_event(pt))
 		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);
+	intel_pt_prep_sample(pt, ptq, event, &sample);
 
-	if (!pt->timeless_decoding)
-		sample.time = tsc_to_perf_time(ptq->timestamp, &pt->tc);
+	sample.id = ptq->pt->instructions_id;
+	sample.stream_id = ptq->pt->instructions_id;
+	sample.period = ptq->state->tot_insn_cnt - ptq->last_insn_cnt;
 
-	sample.cpumode = PERF_RECORD_MISC_USER;
-	sample.ip = ptq->state->from_ip;
-	sample.pid = ptq->pid;
-	sample.tid = ptq->tid;
-	sample.addr = ptq->state->to_ip;
-	sample.id = ptq->pt->transactions_id;
-	sample.stream_id = ptq->pt->transactions_id;
-	sample.period = 1;
-	sample.cpu = ptq->cpu;
-	sample.flags = ptq->flags;
-	sample.insn_len = ptq->insn_len;
-	memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
+	ptq->last_insn_cnt = ptq->state->tot_insn_cnt;
 
-	if (pt->synth_opts.callchain) {
-		thread_stack__sample(ptq->thread, ptq->chain,
-				     pt->synth_opts.callchain_sz, sample.ip);
-		sample.callchain = ptq->chain;
-	}
+	return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
+					    pt->instructions_sample_type);
+}
 
-	if (pt->synth_opts.last_branch) {
-		intel_pt_copy_last_branch_rb(ptq);
-		sample.branch_stack = ptq->last_branch;
-	}
+static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq)
+{
+	struct intel_pt *pt = ptq->pt;
+	union perf_event *event = ptq->event_buf;
+	struct perf_sample sample = { .ip = 0, };
 
-	if (pt->synth_opts.inject) {
-		ret = intel_pt_inject_event(event, &sample,
-					    pt->transactions_sample_type,
-					    pt->synth_needs_swap);
-		if (ret)
-			return ret;
-	}
+	if (intel_pt_skip_event(pt))
+		return 0;
 
-	ret = perf_session__deliver_synth_event(pt->session, event, &sample);
-	if (ret)
-		pr_err("Intel Processor Trace: failed to deliver transaction event, error %d\n",
-		       ret);
+	intel_pt_prep_sample(pt, ptq, event, &sample);
 
-	if (pt->synth_opts.last_branch)
-		intel_pt_reset_last_branch_rb(ptq);
+	sample.id = ptq->pt->transactions_id;
+	sample.stream_id = ptq->pt->transactions_id;
 
-	return ret;
+	return intel_pt_deliver_synth_event(pt, ptq, event, &sample,
+					    pt->transactions_sample_type);
 }
 
 static int intel_pt_synth_error(struct intel_pt *pt, int code, int cpu,
-- 
2.9.4

  parent reply	other threads:[~2017-06-30 22:26 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-30 22:24 [GIT PULL 00/30] perf/core improvements and fixes Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 01/30] perf tests: Add platform dependency to test 15 Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 02/30] perf help: Introduce exec_failed() to avoid code duplication Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 03/30] perf help: Elliminate dup code for reporting Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 04/30] perf help: Use pr_warning() Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 05/30] perf config: " Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 06/30] perf event-parse: " Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 07/30] perf tools: Remove warning() Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 08/30] perf tools: Replace error() with pr_err() Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 09/30] perf config: Do not die when parsing u64 or int config values Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 10/30] perf tools: Kill die() Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 11/30] perf jit: fix typo: "incalid" -> "invalid" Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 12/30] x86/insn: perf tools: Add new ptwrite instruction Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 13/30] perf script: Add 'synth' event type for synthesized events Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 14/30] tools include: Add byte-swapping macros to kernel.h Arnaldo Carvalho de Melo
2017-06-30 22:24 ` [PATCH 15/30] perf auxtrace: Add itrace option to output ptwrite events Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 16/30] perf auxtrace: Add itrace option to output power events Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 17/30] perf script: Add 'synth' field for synthesized event payloads Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 18/30] perf script: Add synthesized Intel PT power and ptwrite events Arnaldo Carvalho de Melo
2017-06-30 22:25 ` Arnaldo Carvalho de Melo [this message]
2017-06-30 22:25 ` [PATCH 20/30] perf intel-pt: Remove unused instructions_sample_period Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 21/30] perf intel-pt: Join needlessly wrapped lines Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 22/30] perf intel-pt: Tidy Intel PT evsel lookup into separate function Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 23/30] perf intel-pt: Tidy messages into called function intel_pt_synth_event() Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 24/30] perf intel-pt: Factor out intel_pt_set_event_name() Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 25/30] perf intel-pt: Move code in intel_pt_synth_events() to simplify attr setting Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 26/30] perf intel-pt: Synthesize new power and "ptwrite" events Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 27/30] perf intel-pt: Add example script for power events and PTWRITE Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 28/30] perf intel-pt: Update documentation to include new ptwrite and power events Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 29/30] perf intel-pt: Do not use TSC packets for calculating CPU cycles to TSC Arnaldo Carvalho de Melo
2017-06-30 22:25 ` [PATCH 30/30] perf auxtrace: Add CPU filter support Arnaldo Carvalho de Melo
2017-07-01  8:41 ` [GIT PULL 00/30] perf/core improvements and fixes Ingo Molnar

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=20170630222514.11832-20-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=ak@linux.intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.