All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Carrillo-Cisneros <davidcc@google.com>
To: linux-kernel@vger.kernel.org
Cc: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Andi Kleen <ak@linux.intel.com>, Simon Que <sque@chromium.org>,
	Wang Nan <wangnan0@huawei.com>, Jiri Olsa <jolsa@kernel.org>,
	He Kuang <hekuang@huawei.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Stephane Eranian <eranian@google.com>,
	Paul Turner <pjt@google.com>,
	David Carrillo-Cisneros <davidcc@google.com>
Subject: [PATCH v3 11/15] perf header: add a buffer to struct feat_fd
Date: Tue,  6 Jun 2017 00:07:18 -0700	[thread overview]
Message-ID: <20170606070722.35213-12-davidcc@google.com> (raw)
In-Reply-To: <20170606070722.35213-1-davidcc@google.com>

Extend struct feat_fd to use a temporal buffer in pipe-mode, instead
of perf.data's file descriptor.

The header features build_id and aux_trace already have logic to
print in file-mode that heavily rely on lseek the file. For now, leave
such features inactive in pipe-mode and print a warning if their
functions are called in pipe-mode.

Signed-off-by: David Carrillo-Cisneros <davidcc@google.com>
---
 tools/perf/util/header.c | 83 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 72 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 323ccd5df382..109675b35fab 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -61,6 +61,7 @@ struct perf_file_attr {
 struct feat_fd {
 	struct perf_header	*ph;
 	int 			fd;
+	void			*buf;	/* Either buf != NULL or fd >= 0 */
 	ssize_t			offset;
 	size_t			size;
 };
@@ -80,18 +81,43 @@ bool perf_header__has_feat(const struct perf_header *header, int feat)
 	return test_bit(feat, header->adds_features);
 }
 
-/* Return: 0 if succeded, -ERR if failed. */
-int do_write(struct feat_fd *ff, const void *buf, size_t size)
+static int __do_write_fd(struct feat_fd *ff, const void *buf, size_t size)
 {
-	ssize_t ret;
+	ssize_t ret = writen(ff->fd, buf, size);
 
-	ret  = writen(ff->fd, buf, size);
 	if (ret != (ssize_t)size)
-		return ret < 0 ? (int)ret: -1;
+		return ret < 0 ? (int)ret : -1;
+	return 0;
+}
+
+static int __do_write_buf(struct feat_fd *ff,  const void *buf, size_t size)
+{
+	void *addr;
+
+retry:
+	if (size > (ff->size - ff->offset)) {
+		addr = realloc(ff->buf, ff->size << 1);
+		if (!addr)
+			return -ENOSPC;
+		ff->buf = addr;
+		ff->size <<= 1;
+		goto retry;
+	}
+
+	memcpy(ff->buf + ff->offset, buf, size);
+	ff->offset += size;
 
 	return 0;
 }
 
+/* Return: 0 if succeded, -ERR if failed. */
+int do_write(struct feat_fd *ff, const void *buf, size_t size)
+{
+	if (!ff->buf)
+		return __do_write_fd(ff, buf, size);
+	return __do_write_buf(ff, buf, size);
+}
+
 /* Return: 0 if succeded, -ERR if failed. */
 int write_padded(struct feat_fd *ff, const void *bf,
 		 size_t count, size_t count_aligned)
@@ -125,13 +151,32 @@ static int do_write_string(struct feat_fd *ff, const char *str)
 	return write_padded(ff, str, olen, len);
 }
 
-static int __do_read(struct feat_fd *ff, void *addr, ssize_t size)
+static int __do_read_fd(struct feat_fd *ff, void *addr, ssize_t size)
 {
-	ssize_t ret = readn(ff->fd, addr, size);
+		ssize_t ret = readn(ff->fd, addr, size);
+
+		if (ret != size)
+			return ret < 0 ? (int)ret : -1;
+		return 0;
+}
+
+static int __do_read_buf(struct feat_fd *ff, void *addr, ssize_t size)
+{
+	if (size > (ssize_t)ff->size - ff->offset)
+		return -1;
+
+	memcpy(addr, ff->buf + ff->offset, size);
+	ff->offset += size;
 
-	if (ret != size)
-		return ret < 0 ? (int)ret : -1;
 	return 0;
+
+}
+
+static int __do_read(struct feat_fd *ff, void *addr, ssize_t size)
+{
+	if (!ff->buf)
+		return __do_read_fd(ff, addr, size);
+	return __do_read_buf(ff, addr, size);
 }
 
 static int do_read_u32(struct feat_fd *ff, u32 *addr)
@@ -188,6 +233,10 @@ static char *do_read_string(struct feat_fd *ff)
 static int write_tracing_data(struct feat_fd *ff,
 			      struct perf_evlist *evlist)
 {
+	if (ff->buf) {
+		WARN_ON("Pipe-mode doesn't supported write_tracing_data.\n");
+		return -1;
+	}
 	return read_tracing_data(ff->fd, &evlist->entries);
 }
 
@@ -202,6 +251,10 @@ static int write_build_id(struct feat_fd *ff,
 	if (!perf_session__read_build_ids(session, true))
 		return -1;
 
+	if (ff->buf) {
+		WARN_ON("Pipe-mode doesn't support write_build_id.\n");
+		return -1;
+	}
 	err = perf_session__write_buildid_table(session, ff);
 	if (err < 0) {
 		pr_debug("failed to write buildid table\n");
@@ -911,6 +964,10 @@ static int write_auxtrace(struct feat_fd *ff,
 	struct perf_session *session;
 	int err;
 
+	if (ff->buf) {
+		pr_err("Unsupported write_auxtrace to memory buffer.\n");
+		return -1;
+	}
 	session = container_of(ff->ph, struct perf_session, header);
 
 	err = auxtrace_index__write(ff->fd, &session->auxtrace_index);
@@ -2192,6 +2249,10 @@ static int do_write_feat(struct feat_fd *ff, int type,
 		if (!feat_ops[type].write)
 			return -1;
 
+		if (ff->buf) {
+			pr_err("Called %s for memory buffer.\n", __func__);
+			return -1;
+		}
 		(*p)->offset = lseek(ff->fd, 0, SEEK_CUR);
 
 		err = feat_ops[type].write(ff, evlist);
@@ -2600,7 +2661,7 @@ static int perf_file_section__process(struct perf_file_section *section,
 				      struct perf_header *ph,
 				      int feat, int fd, void *data)
 {
-	struct feat_fd fdd = {
+	struct feat_fd ff = {
 		.fd	= fd,
 		.ph	= ph,
 		.size	= section->size,
@@ -2621,7 +2682,7 @@ static int perf_file_section__process(struct perf_file_section *section,
 	if (!feat_ops[feat].process)
 		return 0;
 
-	return feat_ops[feat].process(&fdd, data);
+	return feat_ops[feat].process(&ff, data);
 }
 
 static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
-- 
2.13.1.508.gb3defc5cc-goog

  parent reply	other threads:[~2017-06-06  7:08 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-06  7:07 [PATCH v3 00/15] perf tool: add meta-data header support for pipe-mode David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 01/15] perf header: encapsulate read and swap David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 02/15] perf header: add PROCESS_STR_FUN macro David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 03/15] perf header: fail on write_padded error David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 04/15] perf util: add const modifier to buf in "writen" function David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 05/15] perf header: revamp do_write David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 06/15] perf header: add struct feat_fd for write David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 07/15] perf header: use struct feat_fd for print David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 08/15] perf header: use struct feat_fd to process header records David Carrillo-Cisneros
2017-06-08 11:54   ` Jiri Olsa
2017-06-13  4:18     ` David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 09/15] perf header: use struct feat_fd in read " David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 10/15] perf header: make write_pmu_mappings pipe-mode friendly David Carrillo-Cisneros
2017-06-06  7:07 ` David Carrillo-Cisneros [this message]
2017-06-08 11:54   ` [PATCH v3 11/15] perf header: add a buffer to struct feat_fd Jiri Olsa
2017-06-08 11:54   ` Jiri Olsa
2017-06-06  7:07 ` [PATCH v3 12/15] perf header: change FEAT_OP* macros David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 13/15] perf tool: add show_feature_header to perf_tool David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 14/15] perf tools: add feature header record to pipe-mode David Carrillo-Cisneros
2017-06-06  7:07 ` [PATCH v3 15/15] perf header: add event desc to pipe-mode header David Carrillo-Cisneros
2017-06-08 11:54   ` Jiri Olsa
2017-06-13  4:23     ` David Carrillo-Cisneros
2017-06-06 12:35 ` [PATCH v3 00/15] perf tool: add meta-data header support for pipe-mode Jiri Olsa
2017-06-06 18:15   ` David Carrillo-Cisneros
2017-06-07 11:19     ` Jiri Olsa
2017-06-07 15:02       ` David Carrillo-Cisneros
2017-06-13  4:28         ` David Carrillo-Cisneros

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=20170606070722.35213-12-davidcc@google.com \
    --to=davidcc@google.com \
    --cc=acme@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=eranian@google.com \
    --cc=hekuang@huawei.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=pjt@google.com \
    --cc=sque@chromium.org \
    --cc=wangnan0@huawei.com \
    /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.