All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adrian Hunter <adrian.hunter@intel.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>,
	linux-kernel@vger.kernel.org, David Ahern <dsahern@gmail.com>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Jiri Olsa <jolsa@redhat.com>, Namhyung Kim <namhyung@gmail.com>,
	Stephane Eranian <eranian@google.com>
Subject: [PATCH V4 08/24] perf tools: Add AUX area tracing Snapshot Mode
Date: Thu, 30 Apr 2015 17:37:31 +0300	[thread overview]
Message-ID: <1430404667-10593-9-git-send-email-adrian.hunter@intel.com> (raw)
In-Reply-To: <1430404667-10593-1-git-send-email-adrian.hunter@intel.com>

Add support for making snapshots of
AUX area tracing data.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 tools/perf/perf.h          |  3 ++
 tools/perf/util/auxtrace.c | 85 ++++++++++++++++++++++++++++++++++++++++------
 tools/perf/util/auxtrace.h | 41 ++++++++++++++++++++++
 3 files changed, 119 insertions(+), 10 deletions(-)

diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 5042093..aa79fb8 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -55,6 +55,7 @@ struct record_opts {
 	bool	     sample_intr_regs;
 	bool	     running_time;
 	bool	     full_auxtrace;
+	bool	     auxtrace_snapshot_mode;
 	unsigned int freq;
 	unsigned int mmap_pages;
 	unsigned int auxtrace_mmap_pages;
@@ -62,6 +63,8 @@ struct record_opts {
 	u64          branch_stack;
 	u64	     default_interval;
 	u64	     user_interval;
+	size_t	     auxtrace_snapshot_size;
+	const char   *auxtrace_snapshot_opts;
 	bool	     sample_transaction;
 	unsigned     initial_delay;
 	bool         use_clockid;
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 1293710..df66966 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -504,6 +504,29 @@ void auxtrace_record__free(struct auxtrace_record *itr)
 		itr->free(itr);
 }
 
+int auxtrace_record__snapshot_start(struct auxtrace_record *itr)
+{
+	if (itr && itr->snapshot_start)
+		return itr->snapshot_start(itr);
+	return 0;
+}
+
+int auxtrace_record__snapshot_finish(struct auxtrace_record *itr)
+{
+	if (itr && itr->snapshot_finish)
+		return itr->snapshot_finish(itr);
+	return 0;
+}
+
+int auxtrace_record__find_snapshot(struct auxtrace_record *itr, int idx,
+				   struct auxtrace_mmap *mm,
+				   unsigned char *data, u64 *head, u64 *old)
+{
+	if (itr && itr->find_snapshot)
+		return itr->find_snapshot(itr, idx, mm, data, head, old);
+	return 0;
+}
+
 int auxtrace_record__options(struct auxtrace_record *itr,
 			     struct perf_evlist *evlist,
 			     struct record_opts *opts)
@@ -520,6 +543,19 @@ u64 auxtrace_record__reference(struct auxtrace_record *itr)
 	return 0;
 }
 
+int auxtrace_parse_snapshot_options(struct auxtrace_record *itr,
+				    struct record_opts *opts, const char *str)
+{
+	if (!str)
+		return 0;
+
+	if (itr)
+		return itr->parse_snapshot_options(itr, opts, str);
+
+	pr_err("No AUX area tracing to snapshot\n");
+	return -EINVAL;
+}
+
 struct auxtrace_record *__weak
 auxtrace_record__init(struct perf_evlist *evlist __maybe_unused, int *err)
 {
@@ -1077,16 +1113,26 @@ int perf_event__process_auxtrace_error(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
-int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
-			struct perf_tool *tool, process_auxtrace_t fn)
+static int __auxtrace_mmap__read(struct auxtrace_mmap *mm,
+				 struct auxtrace_record *itr,
+				 struct perf_tool *tool, process_auxtrace_t fn,
+				 bool snapshot, size_t snapshot_size)
 {
-	u64 head = auxtrace_mmap__read_head(mm);
-	u64 old = mm->prev, offset, ref;
+	u64 head, old = mm->prev, offset, ref;
 	unsigned char *data = mm->base;
 	size_t size, head_off, old_off, len1, len2, padding;
 	union perf_event ev;
 	void *data1, *data2;
 
+	if (snapshot) {
+		head = auxtrace_mmap__read_snapshot_head(mm);
+		if (auxtrace_record__find_snapshot(itr, mm->idx, mm, data,
+						   &head, &old))
+			return -1;
+	} else {
+		head = auxtrace_mmap__read_head(mm);
+	}
+
 	if (old == head)
 		return 0;
 
@@ -1106,6 +1152,9 @@ int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
 	else
 		size = mm->len - (old_off - head_off);
 
+	if (snapshot && size > snapshot_size)
+		size = snapshot_size;
+
 	ref = auxtrace_record__reference(itr);
 
 	if (head > old || size <= head || mm->mask) {
@@ -1153,18 +1202,34 @@ int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
 
 	mm->prev = head;
 
-	auxtrace_mmap__write_tail(mm, head);
-	if (itr->read_finish) {
-		int err;
+	if (!snapshot) {
+		auxtrace_mmap__write_tail(mm, head);
+		if (itr->read_finish) {
+			int err;
 
-		err = itr->read_finish(itr, mm->idx);
-		if (err < 0)
-			return err;
+			err = itr->read_finish(itr, mm->idx);
+			if (err < 0)
+				return err;
+		}
 	}
 
 	return 1;
 }
 
+int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
+			struct perf_tool *tool, process_auxtrace_t fn)
+{
+	return __auxtrace_mmap__read(mm, itr, tool, fn, false, 0);
+}
+
+int auxtrace_mmap__read_snapshot(struct auxtrace_mmap *mm,
+				 struct auxtrace_record *itr,
+				 struct perf_tool *tool, process_auxtrace_t fn,
+				 size_t snapshot_size)
+{
+	return __auxtrace_mmap__read(mm, itr, tool, fn, true, snapshot_size);
+}
+
 /**
  * struct auxtrace_cache - hash table to implement a cache
  * @hashtable: the hashtable
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 8c6cbb1..c2c677e 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -276,6 +276,10 @@ struct auxtrace_mmap_params {
  * @info_priv_size: return the size of the private data in auxtrace_info_event
  * @info_fill: fill-in the private data in auxtrace_info_event
  * @free: free this auxtrace record structure
+ * @snapshot_start: starting a snapshot
+ * @snapshot_finish: finishing a snapshot
+ * @find_snapshot: find data to snapshot within auxtrace mmap
+ * @parse_snapshot_options: parse snapshot options
  * @reference: provide a 64-bit reference number for auxtrace_event
  * @read_finish: called after reading from an auxtrace mmap
  */
@@ -289,12 +293,36 @@ struct auxtrace_record {
 			 struct auxtrace_info_event *auxtrace_info,
 			 size_t priv_size);
 	void (*free)(struct auxtrace_record *itr);
+	int (*snapshot_start)(struct auxtrace_record *itr);
+	int (*snapshot_finish)(struct auxtrace_record *itr);
+	int (*find_snapshot)(struct auxtrace_record *itr, int idx,
+			     struct auxtrace_mmap *mm, unsigned char *data,
+			     u64 *head, u64 *old);
+	int (*parse_snapshot_options)(struct auxtrace_record *itr,
+				      struct record_opts *opts,
+				      const char *str);
 	u64 (*reference)(struct auxtrace_record *itr);
 	int (*read_finish)(struct auxtrace_record *itr, int idx);
 };
 
 #ifdef HAVE_AUXTRACE_SUPPORT
 
+/*
+ * In snapshot mode the mmapped page is read-only which makes using
+ * __sync_val_compare_and_swap() problematic.  However, snapshot mode expects
+ * the buffer is not updated while the snapshot is made (e.g. Intel PT disables
+ * the event) so there is not a race anyway.
+ */
+static inline u64 auxtrace_mmap__read_snapshot_head(struct auxtrace_mmap *mm)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+	u64 head = ACCESS_ONCE(pc->aux_head);
+
+	/* Ensure all reads are done after we read the head */
+	rmb();
+	return head;
+}
+
 static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
 {
 	struct perf_event_mmap_page *pc = mm->userpg;
@@ -346,6 +374,11 @@ typedef int (*process_auxtrace_t)(struct perf_tool *tool,
 int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
 			struct perf_tool *tool, process_auxtrace_t fn);
 
+int auxtrace_mmap__read_snapshot(struct auxtrace_mmap *mm,
+				 struct auxtrace_record *itr,
+				 struct perf_tool *tool, process_auxtrace_t fn,
+				 size_t snapshot_size);
+
 int auxtrace_queues__init(struct auxtrace_queues *queues);
 int auxtrace_queues__add_event(struct auxtrace_queues *queues,
 			       struct perf_session *session,
@@ -383,6 +416,9 @@ void *auxtrace_cache__lookup(struct auxtrace_cache *c, u32 key);
 struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist,
 					      int *err);
 
+int auxtrace_parse_snapshot_options(struct auxtrace_record *itr,
+				    struct record_opts *opts,
+				    const char *str);
 int auxtrace_record__options(struct auxtrace_record *itr,
 			     struct perf_evlist *evlist,
 			     struct record_opts *opts);
@@ -392,6 +428,11 @@ int auxtrace_record__info_fill(struct auxtrace_record *itr,
 			       struct auxtrace_info_event *auxtrace_info,
 			       size_t priv_size);
 void auxtrace_record__free(struct auxtrace_record *itr);
+int auxtrace_record__snapshot_start(struct auxtrace_record *itr);
+int auxtrace_record__snapshot_finish(struct auxtrace_record *itr);
+int auxtrace_record__find_snapshot(struct auxtrace_record *itr, int idx,
+				   struct auxtrace_mmap *mm,
+				   unsigned char *data, u64 *head, u64 *old);
 u64 auxtrace_record__reference(struct auxtrace_record *itr);
 
 int auxtrace_index__auxtrace_event(struct list_head *head, union perf_event *event,
-- 
1.9.1


  parent reply	other threads:[~2015-04-30 14:40 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-30 14:37 [PATCH V4 00/24] perf tools: Introduce an abstraction for AUX Area and Instruction Tracing Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 01/24] perf report: Fix placement of itrace option in documentation Adrian Hunter
2015-05-06  3:15   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 02/24] perf tools: Add AUX area tracing index Adrian Hunter
2015-05-04 20:02   ` Jiri Olsa
2015-05-06  3:16   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 03/24] perf tools: Hit all build ids when AUX area tracing Adrian Hunter
2015-05-04 20:03   ` Jiri Olsa
2015-05-06  3:16   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 04/24] perf tools: Add build option NO_AUXTRACE to exclude " Adrian Hunter
2015-05-04 20:06   ` Jiri Olsa
2015-05-06  3:16   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 05/24] perf auxtrace: Add option to synthesize events for transactions Adrian Hunter
2015-05-04 20:08   ` Jiri Olsa
2015-05-06  3:17   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 06/24] perf tools: Add support for PERF_RECORD_AUX Adrian Hunter
2015-05-04 20:09   ` Jiri Olsa
2015-05-06  3:17   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 07/24] perf tools: Add support for PERF_RECORD_ITRACE_START Adrian Hunter
2015-05-04 20:10   ` Jiri Olsa
2015-05-06  3:17   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-04-30 14:37 ` Adrian Hunter [this message]
2015-05-04 20:10   ` [PATCH V4 08/24] perf tools: Add AUX area tracing Snapshot Mode Jiri Olsa
2015-05-06  3:17   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 09/24] perf record: Add AUX area tracing Snapshot Mode support Adrian Hunter
2015-05-04 20:11   ` Jiri Olsa
2015-05-06  3:18   ` [tip:perf/core] " tip-bot for Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 10/24] perf auxtrace: Add Intel PT as an AUX area tracing type Adrian Hunter
2015-05-04 20:11   ` Jiri Olsa
2015-04-30 14:37 ` [PATCH V4 11/24] perf tools: Add Intel PT packet decoder Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 12/24] perf tools: Add Intel PT instruction decoder Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 13/24] perf tools: Add Intel PT log Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 14/24] perf tools: Add Intel PT decoder Adrian Hunter
2015-05-11 13:22   ` Arnaldo Carvalho de Melo
2015-05-21 12:58     ` Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 15/24] perf tools: Add Intel PT support Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 16/24] perf tools: Take Intel PT into use Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 17/24] perf tools: Allow auxtrace data alignment Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 18/24] perf tools: Add Intel BTS support Adrian Hunter
2015-05-05 19:51   ` Arnaldo Carvalho de Melo
2015-05-05 21:09     ` Arnaldo Carvalho de Melo
2015-05-06  7:14       ` Adrian Hunter
2015-05-06 13:35         ` Arnaldo Carvalho de Melo
2015-05-07  7:05           ` Adrian Hunter
2015-05-08 19:41             ` Arnaldo Carvalho de Melo
2015-04-30 14:37 ` [PATCH V4 19/24] perf tools: Output sample flags and insn_len from intel_pt Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 20/24] perf tools: Output sample flags and insn_len from intel_bts Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 21/24] perf tools: Intel PT to always update thread stack trace number Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 22/24] perf tools: Intel BTS " Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 23/24] perf tools: Add example call-graph script Adrian Hunter
2015-04-30 14:37 ` [PATCH V4 24/24] perf tools: Put itrace options into an asciidoc include 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=1430404667-10593-9-git-send-email-adrian.hunter@intel.com \
    --to=adrian.hunter@intel.com \
    --cc=acme@kernel.org \
    --cc=dsahern@gmail.com \
    --cc=eranian@google.com \
    --cc=fweisbec@gmail.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=namhyung@gmail.com \
    --cc=peterz@infradead.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.