* [PATCH 0/3] perf tools: Add data file write interface
@ 2013-11-22 14:24 Jiri Olsa
2013-11-22 14:24 ` [PATCH 1/3] perf tools: Add perf_data_file__write interface Jiri Olsa
` (3 more replies)
0 siblings, 4 replies; 21+ messages in thread
From: Jiri Olsa @ 2013-11-22 14:24 UTC (permalink / raw)
To: linux-kernel
Cc: Jiri Olsa, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra,
Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern,
Adrian Hunter
hi,
adding perf_data_file__write function to centralize
output file writes. Using it in record and inject
commands.
David,
patch 2 could colide with your mmap changes, not sure
what's your plan with that in near future, let me know
and I can rebase if needed.
thanks,
jirka
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Stephane Eranian <eranian@google.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
---
Jiri Olsa (3):
perf tools: Add perf_data_file__write interface
perf record: Use perf_data_file__write for output file
perf inject: Handle output file via perf_data_file object
tools/perf/builtin-inject.c | 71 +++++++++++++++++++++++++++++++----------------------------------------
tools/perf/builtin-record.c | 42 +++++++++++++-----------------------------
tools/perf/util/data.c | 20 ++++++++++++++++++++
tools/perf/util/data.h | 15 ++++++++-------
4 files changed, 72 insertions(+), 76 deletions(-)
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 1/3] perf tools: Add perf_data_file__write interface 2013-11-22 14:24 [PATCH 0/3] perf tools: Add data file write interface Jiri Olsa @ 2013-11-22 14:24 ` Jiri Olsa 2013-11-25 19:29 ` Arnaldo Carvalho de Melo 2013-11-22 14:24 ` [PATCH 2/3] perf record: Use perf_data_file__write for output file Jiri Olsa ` (2 subsequent siblings) 3 siblings, 1 reply; 21+ messages in thread From: Jiri Olsa @ 2013-11-22 14:24 UTC (permalink / raw) To: linux-kernel Cc: Jiri Olsa, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter Adding perf_data_file__write interface to centralize output to files. The function prototype is: ssize_t perf_data_file__write(struct perf_data_file *file, void *buf, size_t size); Returns number of bytes written or -1 in case of error. NOTE Indenting 'struct perf_data_file' members, no functional change done. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Stephane Eranian <eranian@google.com> Cc: David Ahern <dsahern@gmail.com> Cc: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/util/data.c | 20 ++++++++++++++++++++ tools/perf/util/data.h | 15 ++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 7d09faf..cce1256 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -118,3 +118,23 @@ void perf_data_file__close(struct perf_data_file *file) { close(file->fd); } + +ssize_t perf_data_file__write(struct perf_data_file *file, + void *buf, size_t size) +{ + ssize_t total = size; + + while (size) { + ssize_t ret = write(file->fd, buf, size); + + if (ret < 0) { + pr_err("failed to write perf data, error: %m\n"); + return -1; + } + + size -= ret; + buf += ret; + } + + return total; +} diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h index 8c2df80..02c53dc 100644 --- a/tools/perf/util/data.h +++ b/tools/perf/util/data.h @@ -9,12 +9,12 @@ enum perf_data_mode { }; struct perf_data_file { - const char *path; - int fd; - bool is_pipe; - bool force; - unsigned long size; - enum perf_data_mode mode; + const char *path; + int fd; + bool is_pipe; + bool force; + unsigned long size; + enum perf_data_mode mode; }; static inline bool perf_data_file__is_read(struct perf_data_file *file) @@ -44,5 +44,6 @@ static inline unsigned long perf_data_file__size(struct perf_data_file *file) int perf_data_file__open(struct perf_data_file *file); void perf_data_file__close(struct perf_data_file *file); - +ssize_t perf_data_file__write(struct perf_data_file *file, + void *buf, size_t size); #endif /* __PERF_DATA_H */ -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 1/3] perf tools: Add perf_data_file__write interface 2013-11-22 14:24 ` [PATCH 1/3] perf tools: Add perf_data_file__write interface Jiri Olsa @ 2013-11-25 19:29 ` Arnaldo Carvalho de Melo 2013-11-26 10:17 ` Jiri Olsa 2013-11-26 17:53 ` [PATCH] tools/perf/util: Document and clean up readn() a bit Ingo Molnar 0 siblings, 2 replies; 21+ messages in thread From: Arnaldo Carvalho de Melo @ 2013-11-25 19:29 UTC (permalink / raw) To: Jiri Olsa Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter Em Fri, Nov 22, 2013 at 03:24:26PM +0100, Jiri Olsa escreveu: > } > + > +ssize_t perf_data_file__write(struct perf_data_file *file, > + void *buf, size_t size) > +{ > + ssize_t total = size; > + > + while (size) { > + ssize_t ret = write(file->fd, buf, size); > + > + if (ret < 0) { > + pr_err("failed to write perf data, error: %m\n"); > + return -1; > + } > + > + size -= ret; > + buf += ret; > + } > + > + return total; So this is the functional equivalent of "readn", so please move it to just after "readn" and make this just a simple wrapper. - Arnaldo ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/3] perf tools: Add perf_data_file__write interface 2013-11-25 19:29 ` Arnaldo Carvalho de Melo @ 2013-11-26 10:17 ` Jiri Olsa 2013-11-26 17:53 ` [PATCH] tools/perf/util: Document and clean up readn() a bit Ingo Molnar 1 sibling, 0 replies; 21+ messages in thread From: Jiri Olsa @ 2013-11-26 10:17 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter On Mon, Nov 25, 2013 at 04:29:09PM -0300, Arnaldo Carvalho de Melo wrote: > Em Fri, Nov 22, 2013 at 03:24:26PM +0100, Jiri Olsa escreveu: > > } > > + > > +ssize_t perf_data_file__write(struct perf_data_file *file, > > + void *buf, size_t size) > > +{ > > + ssize_t total = size; > > + > > + while (size) { > > + ssize_t ret = write(file->fd, buf, size); > > + > > + if (ret < 0) { > > + pr_err("failed to write perf data, error: %m\n"); > > + return -1; > > + } > > + > > + size -= ret; > > + buf += ret; > > + } > > + > > + return total; > > So this is the functional equivalent of "readn", so please move it to > just after "readn" and make this just a simple wrapper. ok, thanks jirka ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH] tools/perf/util: Document and clean up readn() a bit 2013-11-25 19:29 ` Arnaldo Carvalho de Melo 2013-11-26 10:17 ` Jiri Olsa @ 2013-11-26 17:53 ` Ingo Molnar 2013-11-27 8:38 ` Adrian Hunter 1 sibling, 1 reply; 21+ messages in thread From: Ingo Molnar @ 2013-11-26 17:53 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Jiri Olsa, linux-kernel, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter * Arnaldo Carvalho de Melo <acme@ghostprotocols.net> wrote: > Em Fri, Nov 22, 2013 at 03:24:26PM +0100, Jiri Olsa escreveu: > > } > > + > > +ssize_t perf_data_file__write(struct perf_data_file *file, > > + void *buf, size_t size) > > +{ > > + ssize_t total = size; > > + > > + while (size) { > > + ssize_t ret = write(file->fd, buf, size); > > + > > + if (ret < 0) { > > + pr_err("failed to write perf data, error: %m\n"); > > + return -1; > > + } > > + > > + size -= ret; > > + buf += ret; > > + } > > + > > + return total; > > So this is the functional equivalent of "readn", so please move it to > just after "readn" and make this just a simple wrapper. Btw., would be nice to add a small comment to readn() that describes its semantics, it looks like a useful helper. I also added a check for the input parameter 'n', plus I added a 'left' variable to make the flow clearer, and added a debug check for the return value - I think returning 'n' is more obvious. Totally untested though. Thanks, Ingo Signed-off-by: Ingo Molnar <mingo@kernel.org> diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 28a0a89..4789081 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -6,6 +6,7 @@ #endif #include <stdio.h> #include <stdlib.h> +#include <linux/kernel.h> /* * XXX We need to find a better place for these things... @@ -151,21 +152,29 @@ unsigned long convert_unit(unsigned long value, char *unit) return value; } -int readn(int fd, void *buf, size_t n) +/* + * Read exactly 'n' bytes or return an error: + */ +int readn(int fd, void *buf, ssize_t n) { void *buf_start = buf; + size_t left = n; + + BUG_ON(n <= 0); - while (n) { - int ret = read(fd, buf, n); + while (left) { + int ret = read(fd, buf, left); if (ret <= 0) return ret; - n -= ret; + left -= ret; buf += ret; } - return buf - buf_start; + BUG_ON(buf-buf_start != n); + + return n; } size_t hex_width(u64 v) diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index c8f362d..bb0a336 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -253,7 +253,7 @@ bool strlazymatch(const char *str, const char *pat); int strtailcmp(const char *s1, const char *s2); char *strxfrchar(char *s, char from, char to); unsigned long convert_unit(unsigned long value, char *unit); -int readn(int fd, void *buf, size_t size); +int readn(int fd, void *buf, ssize_t size); struct perf_event_attr; ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH] tools/perf/util: Document and clean up readn() a bit 2013-11-26 17:53 ` [PATCH] tools/perf/util: Document and clean up readn() a bit Ingo Molnar @ 2013-11-27 8:38 ` Adrian Hunter 2013-11-27 11:57 ` Ingo Molnar 0 siblings, 1 reply; 21+ messages in thread From: Adrian Hunter @ 2013-11-27 8:38 UTC (permalink / raw) To: Ingo Molnar Cc: Arnaldo Carvalho de Melo, Jiri Olsa, linux-kernel, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern On 26/11/13 19:53, Ingo Molnar wrote: > > * Arnaldo Carvalho de Melo <acme@ghostprotocols.net> wrote: > >> Em Fri, Nov 22, 2013 at 03:24:26PM +0100, Jiri Olsa escreveu: >>> } >>> + >>> +ssize_t perf_data_file__write(struct perf_data_file *file, >>> + void *buf, size_t size) >>> +{ >>> + ssize_t total = size; >>> + >>> + while (size) { >>> + ssize_t ret = write(file->fd, buf, size); >>> + >>> + if (ret < 0) { >>> + pr_err("failed to write perf data, error: %m\n"); >>> + return -1; >>> + } >>> + >>> + size -= ret; >>> + buf += ret; >>> + } >>> + >>> + return total; >> >> So this is the functional equivalent of "readn", so please move it to >> just after "readn" and make this just a simple wrapper. > > Btw., would be nice to add a small comment to readn() that describes > its semantics, it looks like a useful helper. > > I also added a check for the input parameter 'n', plus I added a > 'left' variable to make the flow clearer, and added a debug check for > the return value - I think returning 'n' is more obvious. It would be nicer to match what 'read' does. > > Totally untested though. > > Thanks, > > Ingo > > Signed-off-by: Ingo Molnar <mingo@kernel.org> > > diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c > index 28a0a89..4789081 100644 > --- a/tools/perf/util/util.c > +++ b/tools/perf/util/util.c > @@ -6,6 +6,7 @@ > #endif > #include <stdio.h> > #include <stdlib.h> > +#include <linux/kernel.h> > > /* > * XXX We need to find a better place for these things... > @@ -151,21 +152,29 @@ unsigned long convert_unit(unsigned long value, char *unit) > return value; > } > > -int readn(int fd, void *buf, size_t n) > +/* > + * Read exactly 'n' bytes or return an error: > + */ > +int readn(int fd, void *buf, ssize_t n) Should really be the same prototype as 'read' i.e. ssize_t readn(int fd, void *buf, size_t n) Need to change callers that are using 'int' too. > { > void *buf_start = buf; > + size_t left = n; > + > + BUG_ON(n <= 0); BUG_ON(n == 0 || n > SSIZE_MAX); > > - while (n) { > - int ret = read(fd, buf, n); > + while (left) { > + int ret = read(fd, buf, left); Should use the correct return type: ssize_t ret = read(fd, buf, left); > > if (ret <= 0) > return ret; Don't return 0 if not all the bytes were read: if (ret < 0) return ret; if (!ret) break; > > - n -= ret; > + left -= ret; > buf += ret; > } > > - return buf - buf_start; > + BUG_ON(buf-buf_start != n); > + > + return n; Should return the same value as 'read' i.e the original return buf - buf_start; > } > > size_t hex_width(u64 v) > diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h > index c8f362d..bb0a336 100644 > --- a/tools/perf/util/util.h > +++ b/tools/perf/util/util.h > @@ -253,7 +253,7 @@ bool strlazymatch(const char *str, const char *pat); > int strtailcmp(const char *s1, const char *s2); > char *strxfrchar(char *s, char from, char to); > unsigned long convert_unit(unsigned long value, char *unit); > -int readn(int fd, void *buf, size_t size); > +int readn(int fd, void *buf, ssize_t size); > > struct perf_event_attr; > > > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] tools/perf/util: Document and clean up readn() a bit 2013-11-27 8:38 ` Adrian Hunter @ 2013-11-27 11:57 ` Ingo Molnar 2013-11-27 15:19 ` David Ahern 0 siblings, 1 reply; 21+ messages in thread From: Ingo Molnar @ 2013-11-27 11:57 UTC (permalink / raw) To: Adrian Hunter Cc: Arnaldo Carvalho de Melo, Jiri Olsa, linux-kernel, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern * Adrian Hunter <adrian.hunter@intel.com> wrote: > On 26/11/13 19:53, Ingo Molnar wrote: > > > > * Arnaldo Carvalho de Melo <acme@ghostprotocols.net> wrote: > > > >> Em Fri, Nov 22, 2013 at 03:24:26PM +0100, Jiri Olsa escreveu: > >>> } > >>> + > >>> +ssize_t perf_data_file__write(struct perf_data_file *file, > >>> + void *buf, size_t size) > >>> +{ > >>> + ssize_t total = size; > >>> + > >>> + while (size) { > >>> + ssize_t ret = write(file->fd, buf, size); > >>> + > >>> + if (ret < 0) { > >>> + pr_err("failed to write perf data, error: %m\n"); > >>> + return -1; > >>> + } > >>> + > >>> + size -= ret; > >>> + buf += ret; > >>> + } > >>> + > >>> + return total; > >> > >> So this is the functional equivalent of "readn", so please move it to > >> just after "readn" and make this just a simple wrapper. > > > > Btw., would be nice to add a small comment to readn() that describes > > its semantics, it looks like a useful helper. > > > > I also added a check for the input parameter 'n', plus I added a > > 'left' variable to make the flow clearer, and added a debug check for > > the return value - I think returning 'n' is more obvious. > > It would be nicer to match what 'read' does. > > > > > Totally untested though. > > > > Thanks, > > > > Ingo > > > > Signed-off-by: Ingo Molnar <mingo@kernel.org> > > > > diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c > > index 28a0a89..4789081 100644 > > --- a/tools/perf/util/util.c > > +++ b/tools/perf/util/util.c > > @@ -6,6 +6,7 @@ > > #endif > > #include <stdio.h> > > #include <stdlib.h> > > +#include <linux/kernel.h> > > > > /* > > * XXX We need to find a better place for these things... > > @@ -151,21 +152,29 @@ unsigned long convert_unit(unsigned long value, char *unit) > > return value; > > } > > > > -int readn(int fd, void *buf, size_t n) > > +/* > > + * Read exactly 'n' bytes or return an error: > > + */ > > +int readn(int fd, void *buf, ssize_t n) > > Should really be the same prototype as 'read' i.e. > > ssize_t readn(int fd, void *buf, size_t n) > > Need to change callers that are using 'int' too. > > > { > > void *buf_start = buf; > > + size_t left = n; > > + > > + BUG_ON(n <= 0); > > BUG_ON(n == 0 || n > SSIZE_MAX); > > > > > - while (n) { > > - int ret = read(fd, buf, n); > > + while (left) { > > + int ret = read(fd, buf, left); > > Should use the correct return type: > > ssize_t ret = read(fd, buf, left); > > > > > if (ret <= 0) > > return ret; > > Don't return 0 if not all the bytes were read: > > if (ret < 0) > return ret; > if (!ret) > break; Okay, I thought this was an intentional 'all or nothing' interface - but looking at the readn() users they can tolerate partial results just fine. > > > > > - n -= ret; > > + left -= ret; > > buf += ret; > > } > > > > - return buf - buf_start; > > + BUG_ON(buf-buf_start != n); > > + > > + return n; > > Should return the same value as 'read' i.e the original > > return buf - buf_start; It does, in the original version I patched buf-buf_start == n, see the assert that checks for that. If partial reads are returned then this bit has to change too, yes. Thanks, Ingo ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] tools/perf/util: Document and clean up readn() a bit 2013-11-27 11:57 ` Ingo Molnar @ 2013-11-27 15:19 ` David Ahern 2013-11-27 15:50 ` Jiri Olsa 0 siblings, 1 reply; 21+ messages in thread From: David Ahern @ 2013-11-27 15:19 UTC (permalink / raw) To: Ingo Molnar, Adrian Hunter Cc: Arnaldo Carvalho de Melo, Jiri Olsa, linux-kernel, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian On 11/27/13, 4:57 AM, Ingo Molnar wrote: > Okay, I thought this was an intentional 'all or nothing' interface - > but looking at the readn() users they can tolerate partial results > just fine. I believe that is the intent -- an all or nothing interface. David ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] tools/perf/util: Document and clean up readn() a bit 2013-11-27 15:19 ` David Ahern @ 2013-11-27 15:50 ` Jiri Olsa 2013-11-27 15:54 ` Ingo Molnar 0 siblings, 1 reply; 21+ messages in thread From: Jiri Olsa @ 2013-11-27 15:50 UTC (permalink / raw) To: David Ahern Cc: Ingo Molnar, Adrian Hunter, Arnaldo Carvalho de Melo, linux-kernel, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian On Wed, Nov 27, 2013 at 08:19:13AM -0700, David Ahern wrote: > On 11/27/13, 4:57 AM, Ingo Molnar wrote: > >Okay, I thought this was an intentional 'all or nothing' interface - > >but looking at the readn() users they can tolerate partial results > >just fine. > > I believe that is the intent -- an all or nothing interface. all the users either checks the returned value with the size or do (ret < 0) and fail and one instance in the read_attr does not check anything and blindly hopes it will read all ;-) I have similar patch that also change callers to use proper ssize_t instead of int.. I can rebase and send it separately or combine it with yours.. let me know jirka ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] tools/perf/util: Document and clean up readn() a bit 2013-11-27 15:50 ` Jiri Olsa @ 2013-11-27 15:54 ` Ingo Molnar 0 siblings, 0 replies; 21+ messages in thread From: Ingo Molnar @ 2013-11-27 15:54 UTC (permalink / raw) To: Jiri Olsa Cc: David Ahern, Adrian Hunter, Arnaldo Carvalho de Melo, linux-kernel, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian * Jiri Olsa <jolsa@redhat.com> wrote: > On Wed, Nov 27, 2013 at 08:19:13AM -0700, David Ahern wrote: > > On 11/27/13, 4:57 AM, Ingo Molnar wrote: > > >Okay, I thought this was an intentional 'all or nothing' interface - > > >but looking at the readn() users they can tolerate partial results > > >just fine. > > > > I believe that is the intent -- an all or nothing interface. > > all the users either checks the returned value with the size > or do (ret < 0) and fail so, a 'ret < 0' check would actually be sensitive to whether readn() is an all-or-nothing interface (today), or a partial interface (the suggestion). So it appears keeping it all-or-nothing (i.e. my patch) is the right approach. > and one instance in the read_attr does not check anything and > blindly hopes it will read all ;-) > > I have similar patch that also change callers to use proper ssize_t > instead of int.. I can rebase and send it separately or combine it > with yours.. let me know Sure ... I just noticed a few patterns. Feel free to use all (or none ;-) of my patch in your series. Thanks, Ingo ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 2/3] perf record: Use perf_data_file__write for output file 2013-11-22 14:24 [PATCH 0/3] perf tools: Add data file write interface Jiri Olsa 2013-11-22 14:24 ` [PATCH 1/3] perf tools: Add perf_data_file__write interface Jiri Olsa @ 2013-11-22 14:24 ` Jiri Olsa 2013-11-25 19:31 ` Arnaldo Carvalho de Melo 2013-11-22 14:24 ` [PATCH 3/3] perf inject: Handle output file via perf_data_file object Jiri Olsa 2013-11-22 15:01 ` [PATCH 0/3] perf tools: Add data file write interface David Ahern 3 siblings, 1 reply; 21+ messages in thread From: Jiri Olsa @ 2013-11-22 14:24 UTC (permalink / raw) To: linux-kernel Cc: Jiri Olsa, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter Changing the file output code to use the newly added perf_data_file__write interface. No functional change intended. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Stephane Eranian <eranian@google.com> Cc: David Ahern <dsahern@gmail.com> Cc: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/builtin-record.c | 42 +++++++++++++----------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 65615a8..bc3c7be 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -76,42 +76,27 @@ struct perf_record { long samples; }; -static int do_write_output(struct perf_record *rec, void *buf, size_t size) +static ssize_t perf_record__write(struct perf_record *rec, + void *buf, size_t size) { - struct perf_data_file *file = &rec->file; - - while (size) { - ssize_t ret = write(file->fd, buf, size); - - if (ret < 0) { - pr_err("failed to write perf data, error: %m\n"); - return -1; - } - - size -= ret; - buf += ret; + struct perf_session *session = rec->session; + ssize_t ret; - rec->bytes_written += ret; - } + ret = perf_data_file__write(session->file, buf, size); + if (ret < 0) + return -1; + rec->bytes_written += ret; return 0; } -static int write_output(struct perf_record *rec, void *buf, size_t size) -{ - return do_write_output(rec, buf, size); -} - static int process_synthesized_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { struct perf_record *rec = container_of(tool, struct perf_record, tool); - if (write_output(rec, event, event->header.size) < 0) - return -1; - - return 0; + return perf_record__write(rec, event, event->header.size); } static int perf_record__mmap_read(struct perf_record *rec, @@ -136,7 +121,7 @@ static int perf_record__mmap_read(struct perf_record *rec, size = md->mask + 1 - (old & md->mask); old += size; - if (write_output(rec, buf, size) < 0) { + if (perf_record__write(rec, buf, size) < 0) { rc = -1; goto out; } @@ -146,7 +131,7 @@ static int perf_record__mmap_read(struct perf_record *rec, size = head - old; old += size; - if (write_output(rec, buf, size) < 0) { + if (perf_record__write(rec, buf, size) < 0) { rc = -1; goto out; } @@ -322,8 +307,7 @@ static struct perf_event_header finished_round_event = { static int perf_record__mmap_read_all(struct perf_record *rec) { - int i; - int rc = 0; + int i, rc = 0; for (i = 0; i < rec->evlist->nr_mmaps; i++) { if (rec->evlist->mmap[i].base) { @@ -335,7 +319,7 @@ static int perf_record__mmap_read_all(struct perf_record *rec) } if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) - rc = write_output(rec, &finished_round_event, + rc = perf_record__write(rec, &finished_round_event, sizeof(finished_round_event)); out: -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/3] perf record: Use perf_data_file__write for output file 2013-11-22 14:24 ` [PATCH 2/3] perf record: Use perf_data_file__write for output file Jiri Olsa @ 2013-11-25 19:31 ` Arnaldo Carvalho de Melo 2013-11-26 10:16 ` Jiri Olsa 0 siblings, 1 reply; 21+ messages in thread From: Arnaldo Carvalho de Melo @ 2013-11-25 19:31 UTC (permalink / raw) To: Jiri Olsa Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter Em Fri, Nov 22, 2013 at 03:24:27PM +0100, Jiri Olsa escreveu: > Changing the file output code to use the newly > added perf_data_file__write interface. So I like renaming write_output() to perf_record__write(), but then you're lumping together this change and the other, which is to make write_output, now renamed to perf_record__write() to use perf_data_file. Can you please split it like that? - Arnaldo > No functional change intended. > > Signed-off-by: Jiri Olsa <jolsa@redhat.com> > Cc: Ingo Molnar <mingo@kernel.org> > Cc: Frederic Weisbecker <fweisbec@gmail.com> > Cc: Peter Zijlstra <peterz@infradead.org> > Cc: Namhyung Kim <namhyung@kernel.org> > Cc: Mike Galbraith <efault@gmx.de> > Cc: Stephane Eranian <eranian@google.com> > Cc: David Ahern <dsahern@gmail.com> > Cc: Adrian Hunter <adrian.hunter@intel.com> > --- > tools/perf/builtin-record.c | 42 +++++++++++++----------------------------- > 1 file changed, 13 insertions(+), 29 deletions(-) > > diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c > index 65615a8..bc3c7be 100644 > --- a/tools/perf/builtin-record.c > +++ b/tools/perf/builtin-record.c > @@ -76,42 +76,27 @@ struct perf_record { > long samples; > }; > > -static int do_write_output(struct perf_record *rec, void *buf, size_t size) > +static ssize_t perf_record__write(struct perf_record *rec, > + void *buf, size_t size) > { > - struct perf_data_file *file = &rec->file; > - > - while (size) { > - ssize_t ret = write(file->fd, buf, size); > - > - if (ret < 0) { > - pr_err("failed to write perf data, error: %m\n"); > - return -1; > - } > - > - size -= ret; > - buf += ret; > + struct perf_session *session = rec->session; > + ssize_t ret; > > - rec->bytes_written += ret; > - } > + ret = perf_data_file__write(session->file, buf, size); > + if (ret < 0) > + return -1; > > + rec->bytes_written += ret; > return 0; > } > > -static int write_output(struct perf_record *rec, void *buf, size_t size) > -{ > - return do_write_output(rec, buf, size); > -} > - > static int process_synthesized_event(struct perf_tool *tool, > union perf_event *event, > struct perf_sample *sample __maybe_unused, > struct machine *machine __maybe_unused) > { > struct perf_record *rec = container_of(tool, struct perf_record, tool); > - if (write_output(rec, event, event->header.size) < 0) > - return -1; > - > - return 0; > + return perf_record__write(rec, event, event->header.size); > } > > static int perf_record__mmap_read(struct perf_record *rec, > @@ -136,7 +121,7 @@ static int perf_record__mmap_read(struct perf_record *rec, > size = md->mask + 1 - (old & md->mask); > old += size; > > - if (write_output(rec, buf, size) < 0) { > + if (perf_record__write(rec, buf, size) < 0) { > rc = -1; > goto out; > } > @@ -146,7 +131,7 @@ static int perf_record__mmap_read(struct perf_record *rec, > size = head - old; > old += size; > > - if (write_output(rec, buf, size) < 0) { > + if (perf_record__write(rec, buf, size) < 0) { > rc = -1; > goto out; > } > @@ -322,8 +307,7 @@ static struct perf_event_header finished_round_event = { > > static int perf_record__mmap_read_all(struct perf_record *rec) > { > - int i; > - int rc = 0; > + int i, rc = 0; > > for (i = 0; i < rec->evlist->nr_mmaps; i++) { > if (rec->evlist->mmap[i].base) { > @@ -335,7 +319,7 @@ static int perf_record__mmap_read_all(struct perf_record *rec) > } > > if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) > - rc = write_output(rec, &finished_round_event, > + rc = perf_record__write(rec, &finished_round_event, > sizeof(finished_round_event)); > > out: > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/3] perf record: Use perf_data_file__write for output file 2013-11-25 19:31 ` Arnaldo Carvalho de Melo @ 2013-11-26 10:16 ` Jiri Olsa 0 siblings, 0 replies; 21+ messages in thread From: Jiri Olsa @ 2013-11-26 10:16 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter On Mon, Nov 25, 2013 at 04:31:37PM -0300, Arnaldo Carvalho de Melo wrote: > Em Fri, Nov 22, 2013 at 03:24:27PM +0100, Jiri Olsa escreveu: > > Changing the file output code to use the newly > > added perf_data_file__write interface. > > So I like renaming write_output() to perf_record__write(), but then > you're lumping together this change and the other, which is to make > write_output, now renamed to perf_record__write() to use perf_data_file. > > Can you please split it like that? > ok, will do thanks, jirka ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 3/3] perf inject: Handle output file via perf_data_file object 2013-11-22 14:24 [PATCH 0/3] perf tools: Add data file write interface Jiri Olsa 2013-11-22 14:24 ` [PATCH 1/3] perf tools: Add perf_data_file__write interface Jiri Olsa 2013-11-22 14:24 ` [PATCH 2/3] perf record: Use perf_data_file__write for output file Jiri Olsa @ 2013-11-22 14:24 ` Jiri Olsa 2013-11-25 19:40 ` Arnaldo Carvalho de Melo 2013-11-22 15:01 ` [PATCH 0/3] perf tools: Add data file write interface David Ahern 3 siblings, 1 reply; 21+ messages in thread From: Jiri Olsa @ 2013-11-22 14:24 UTC (permalink / raw) To: linux-kernel Cc: Jiri Olsa, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter Using the perf_data_file object to handle output file processing. No functional change intended. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Stephane Eranian <eranian@google.com> Cc: David Ahern <dsahern@gmail.com> Cc: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/builtin-inject.c | 71 ++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 6a25085..654a33e 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -22,14 +22,13 @@ #include <linux/list.h> struct perf_inject { - struct perf_tool tool; - bool build_ids; - bool sched_stat; - const char *input_name; - int pipe_output, - output; - u64 bytes_written; - struct list_head samples; + struct perf_tool tool; + bool build_ids; + bool sched_stat; + const char *input_name; + struct perf_data_file output; + u64 bytes_written; + struct list_head samples; }; struct event_entry { @@ -42,21 +41,14 @@ static int perf_event__repipe_synth(struct perf_tool *tool, union perf_event *event) { struct perf_inject *inject = container_of(tool, struct perf_inject, tool); - uint32_t size; - void *buf = event; + ssize_t size; - size = event->header.size; - - while (size) { - int ret = write(inject->output, buf, size); - if (ret < 0) - return -errno; - - size -= ret; - buf += ret; - inject->bytes_written += ret; - } + size = perf_data_file__write(&inject->output, event, + event->header.size); + if (size < 0) + return -errno; + inject->bytes_written += size; return 0; } @@ -80,7 +72,7 @@ static int perf_event__repipe_attr(struct perf_tool *tool, if (ret) return ret; - if (!inject->pipe_output) + if (!perf_data_file__is_pipe(&inject->output)) return 0; return perf_event__repipe_synth(tool, event); @@ -351,10 +343,12 @@ static int __cmd_inject(struct perf_inject *inject) { struct perf_session *session; int ret = -EINVAL; - struct perf_data_file file = { + struct perf_data_file file_in = { .path = inject->input_name, .mode = PERF_DATA_MODE_READ, }; + struct perf_data_file *file_out = &inject->output; + int out_fd = perf_data_file__fd(file_out); signal(SIGINT, sig_handler); @@ -365,7 +359,7 @@ static int __cmd_inject(struct perf_inject *inject) inject->tool.tracing_data = perf_event__repipe_tracing_data; } - session = perf_session__new(&file, true, &inject->tool); + session = perf_session__new(&file_in, true, &inject->tool); if (session == NULL) return -ENOMEM; @@ -391,14 +385,15 @@ static int __cmd_inject(struct perf_inject *inject) } } - if (!inject->pipe_output) - lseek(inject->output, session->header.data_offset, SEEK_SET); + if (!perf_data_file__is_pipe(file_out)) + lseek(out_fd, session->header.data_offset, SEEK_SET); ret = perf_session__process_events(session, &inject->tool); - if (!inject->pipe_output) { + if (!perf_data_file__is_pipe(file_out)) { session->header.data_size = inject->bytes_written; - perf_session__write_header(session, session->evlist, inject->output, true); + perf_session__write_header(session, session->evlist, out_fd, + true); } perf_session__delete(session); @@ -427,14 +422,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) }, .input_name = "-", .samples = LIST_HEAD_INIT(inject.samples), + .output = { + .path = "-", + .mode = PERF_DATA_MODE_WRITE, + }, }; - const char *output_name = "-"; const struct option options[] = { OPT_BOOLEAN('b', "build-ids", &inject.build_ids, "Inject build-ids into the output stream"), OPT_STRING('i', "input", &inject.input_name, "file", "input file name"), - OPT_STRING('o', "output", &output_name, "file", + OPT_STRING('o', "output", &inject.output.path, "file", "output file name"), OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, "Merge sched-stat and sched-switch for getting events " @@ -456,16 +454,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) if (argc) usage_with_options(inject_usage, options); - if (!strcmp(output_name, "-")) { - inject.pipe_output = 1; - inject.output = STDOUT_FILENO; - } else { - inject.output = open(output_name, O_CREAT | O_WRONLY | O_TRUNC, - S_IRUSR | S_IWUSR); - if (inject.output < 0) { - perror("failed to create output file"); - return -1; - } + if (perf_data_file__open(&inject.output)) { + perror("failed to create output file"); + return -1; } if (symbol__init() < 0) -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] perf inject: Handle output file via perf_data_file object 2013-11-22 14:24 ` [PATCH 3/3] perf inject: Handle output file via perf_data_file object Jiri Olsa @ 2013-11-25 19:40 ` Arnaldo Carvalho de Melo 2013-11-26 10:03 ` Jiri Olsa 0 siblings, 1 reply; 21+ messages in thread From: Arnaldo Carvalho de Melo @ 2013-11-25 19:40 UTC (permalink / raw) To: Jiri Olsa Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter Em Fri, Nov 22, 2013 at 03:24:28PM +0100, Jiri Olsa escreveu: > Using the perf_data_file object to handle output > file processing. > > No functional change intended. > > Signed-off-by: Jiri Olsa <jolsa@redhat.com> > Cc: Ingo Molnar <mingo@kernel.org> > Cc: Frederic Weisbecker <fweisbec@gmail.com> > Cc: Peter Zijlstra <peterz@infradead.org> > Cc: Namhyung Kim <namhyung@kernel.org> > Cc: Mike Galbraith <efault@gmx.de> > Cc: Stephane Eranian <eranian@google.com> > Cc: David Ahern <dsahern@gmail.com> > Cc: Adrian Hunter <adrian.hunter@intel.com> > --- > tools/perf/builtin-inject.c | 71 ++++++++++++++++++++------------------------- > 1 file changed, 31 insertions(+), 40 deletions(-) > > diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c > index 6a25085..654a33e 100644 > --- a/tools/perf/builtin-inject.c > +++ b/tools/perf/builtin-inject.c > @@ -22,14 +22,13 @@ > #include <linux/list.h> > > struct perf_inject { > - struct perf_tool tool; > - bool build_ids; > - bool sched_stat; > - const char *input_name; > - int pipe_output, > - output; > - u64 bytes_written; > - struct list_head samples; > + struct perf_tool tool; > + bool build_ids; > + bool sched_stat; > + const char *input_name; > + struct perf_data_file output; > + u64 bytes_written; > + struct list_head samples; > }; > > struct event_entry { > @@ -42,21 +41,14 @@ static int perf_event__repipe_synth(struct perf_tool *tool, > union perf_event *event) > { > struct perf_inject *inject = container_of(tool, struct perf_inject, tool); > - uint32_t size; > - void *buf = event; > + ssize_t size; > > - size = event->header.size; > - > - while (size) { > - int ret = write(inject->output, buf, size); > - if (ret < 0) > - return -errno; > - > - size -= ret; > - buf += ret; > - inject->bytes_written += ret; > - } > + size = perf_data_file__write(&inject->output, event, > + event->header.size); > + if (size < 0) > + return -errno; > > + inject->bytes_written += size; > return 0; > } > > @@ -80,7 +72,7 @@ static int perf_event__repipe_attr(struct perf_tool *tool, > if (ret) > return ret; > > - if (!inject->pipe_output) > + if (!perf_data_file__is_pipe(&inject->output)) > return 0; > > return perf_event__repipe_synth(tool, event); > @@ -351,10 +343,12 @@ static int __cmd_inject(struct perf_inject *inject) > { > struct perf_session *session; > int ret = -EINVAL; > - struct perf_data_file file = { > + struct perf_data_file file_in = { Why don't leave it as 'file', and on a follow up patch _then_ rename it to file_in? This way patch review gets easier, i.e. try avoiding doing multiple things per patch. > .path = inject->input_name, > .mode = PERF_DATA_MODE_READ, > }; > + struct perf_data_file *file_out = &inject->output; > + int out_fd = perf_data_file__fd(file_out); > > signal(SIGINT, sig_handler); > > @@ -365,7 +359,7 @@ static int __cmd_inject(struct perf_inject *inject) > inject->tool.tracing_data = perf_event__repipe_tracing_data; > } > > - session = perf_session__new(&file, true, &inject->tool); > + session = perf_session__new(&file_in, true, &inject->tool); This hunk, for example, wouldn't be here, the this patch would be shorter, easier to review. > if (session == NULL) > return -ENOMEM; > > @@ -391,14 +385,15 @@ static int __cmd_inject(struct perf_inject *inject) > } > } > > - if (!inject->pipe_output) > - lseek(inject->output, session->header.data_offset, SEEK_SET); > + if (!perf_data_file__is_pipe(file_out)) > + lseek(out_fd, session->header.data_offset, SEEK_SET); Couldn't this be left as: - if (!inject->pipe_output) - lseek(inject->output, session->header.data_offset, SEEK_SET); + if (!perf_data_file__is_pipe(file_out)) + lseek(inject->output->fd, session->header.data_offset, SEEK_SET); I.e. why wrap access to the fd like that? > > ret = perf_session__process_events(session, &inject->tool); > > - if (!inject->pipe_output) { > + if (!perf_data_file__is_pipe(file_out)) { > session->header.data_size = inject->bytes_written; > - perf_session__write_header(session, session->evlist, inject->output, true); > + perf_session__write_header(session, session->evlist, out_fd, > + true); Why a line for 'true' all by itself? > } > > perf_session__delete(session); > @@ -427,14 +422,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) > }, > .input_name = "-", > .samples = LIST_HEAD_INIT(inject.samples), > + .output = { > + .path = "-", > + .mode = PERF_DATA_MODE_WRITE, > + }, > }; > - const char *output_name = "-"; > const struct option options[] = { > OPT_BOOLEAN('b', "build-ids", &inject.build_ids, > "Inject build-ids into the output stream"), > OPT_STRING('i', "input", &inject.input_name, "file", > "input file name"), > - OPT_STRING('o', "output", &output_name, "file", > + OPT_STRING('o', "output", &inject.output.path, "file", see, here you directly access a perf_data_file member instead of having another wrapper :-) > "output file name"), > OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, > "Merge sched-stat and sched-switch for getting events " > @@ -456,16 +454,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) > if (argc) > usage_with_options(inject_usage, options); > > - if (!strcmp(output_name, "-")) { > - inject.pipe_output = 1; > - inject.output = STDOUT_FILENO; > - } else { > - inject.output = open(output_name, O_CREAT | O_WRONLY | O_TRUNC, > - S_IRUSR | S_IWUSR); > - if (inject.output < 0) { > - perror("failed to create output file"); > - return -1; > - } > + if (perf_data_file__open(&inject.output)) { > + perror("failed to create output file"); > + return -1; > } > > if (symbol__init() < 0) > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] perf inject: Handle output file via perf_data_file object 2013-11-25 19:40 ` Arnaldo Carvalho de Melo @ 2013-11-26 10:03 ` Jiri Olsa 2013-11-26 12:42 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 21+ messages in thread From: Jiri Olsa @ 2013-11-26 10:03 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter On Mon, Nov 25, 2013 at 04:40:32PM -0300, Arnaldo Carvalho de Melo wrote: > Em Fri, Nov 22, 2013 at 03:24:28PM +0100, Jiri Olsa escreveu: > > Using the perf_data_file object to handle output SNIP > > + if (!perf_data_file__is_pipe(&inject->output)) > > return 0; > > > > return perf_event__repipe_synth(tool, event); > > @@ -351,10 +343,12 @@ static int __cmd_inject(struct perf_inject *inject) > > { > > struct perf_session *session; > > int ret = -EINVAL; > > - struct perf_data_file file = { > > + struct perf_data_file file_in = { > > Why don't leave it as 'file', and on a follow up patch _then_ rename it > to file_in? This way patch review gets easier, i.e. try avoiding doing > multiple things per patch. the input file needed to be renamed, because new 'output' file was added > > > .path = inject->input_name, > > .mode = PERF_DATA_MODE_READ, > > }; > > + struct perf_data_file *file_out = &inject->output; > > + int out_fd = perf_data_file__fd(file_out); > > > > signal(SIGINT, sig_handler); > > > > @@ -365,7 +359,7 @@ static int __cmd_inject(struct perf_inject *inject) > > inject->tool.tracing_data = perf_event__repipe_tracing_data; > > } > > > > - session = perf_session__new(&file, true, &inject->tool); > > + session = perf_session__new(&file_in, true, &inject->tool); > > This hunk, for example, wouldn't be here, the this patch would be > shorter, easier to review. > > > if (session == NULL) > > return -ENOMEM; > > > > @@ -391,14 +385,15 @@ static int __cmd_inject(struct perf_inject *inject) > > } > > } > > > > - if (!inject->pipe_output) > > - lseek(inject->output, session->header.data_offset, SEEK_SET); > > + if (!perf_data_file__is_pipe(file_out)) > > + lseek(out_fd, session->header.data_offset, SEEK_SET); > > Couldn't this be left as: > > - if (!inject->pipe_output) > - lseek(inject->output, session->header.data_offset, SEEK_SET); > + if (!perf_data_file__is_pipe(file_out)) > + lseek(inject->output->fd, session->header.data_offset, SEEK_SET); > > I.e. why wrap access to the fd like that? well, inject->output->fd is used on 2 places within the function, so it seems logical to put it into variable and use it like that > > > > > ret = perf_session__process_events(session, &inject->tool); > > > > - if (!inject->pipe_output) { > > + if (!perf_data_file__is_pipe(file_out)) { > > session->header.data_size = inject->bytes_written; > > - perf_session__write_header(session, session->evlist, inject->output, true); > > + perf_session__write_header(session, session->evlist, out_fd, > > + true); > > Why a line for 'true' all by itself? line was crossing 80 chars limit > > > } > > > > perf_session__delete(session); > > @@ -427,14 +422,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) > > }, > > .input_name = "-", > > .samples = LIST_HEAD_INIT(inject.samples), > > + .output = { > > + .path = "-", > > + .mode = PERF_DATA_MODE_WRITE, > > + }, > > }; > > - const char *output_name = "-"; > > const struct option options[] = { > > OPT_BOOLEAN('b', "build-ids", &inject.build_ids, > > "Inject build-ids into the output stream"), > > OPT_STRING('i', "input", &inject.input_name, "file", > > "input file name"), > > - OPT_STRING('o', "output", &output_name, "file", > > + OPT_STRING('o', "output", &inject.output.path, "file", > > see, here you directly access a perf_data_file member instead of having > another wrapper :-) yes I dont have strong opinions about wrappers, sometimes it seems appropriate, sometimes it does not.. tell me the guidance here and I'll kick the patch to fit ;-) thanks, jirka ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] perf inject: Handle output file via perf_data_file object 2013-11-26 10:03 ` Jiri Olsa @ 2013-11-26 12:42 ` Arnaldo Carvalho de Melo 2013-11-26 13:07 ` Jiri Olsa 0 siblings, 1 reply; 21+ messages in thread From: Arnaldo Carvalho de Melo @ 2013-11-26 12:42 UTC (permalink / raw) To: Jiri Olsa Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter Em Tue, Nov 26, 2013 at 11:03:24AM +0100, Jiri Olsa escreveu: > On Mon, Nov 25, 2013 at 04:40:32PM -0300, Arnaldo Carvalho de Melo wrote: > > Em Fri, Nov 22, 2013 at 03:24:28PM +0100, Jiri Olsa escreveu: > > > Using the perf_data_file object to handle output > SNIP > > > + if (!perf_data_file__is_pipe(&inject->output)) > > > return 0; > > > return perf_event__repipe_synth(tool, event); > > > @@ -351,10 +343,12 @@ static int __cmd_inject(struct perf_inject *inject) > > > { > > > struct perf_session *session; > > > int ret = -EINVAL; > > > - struct perf_data_file file = { > > > + struct perf_data_file file_in = { > > > > Why don't leave it as 'file', and on a follow up patch _then_ rename it > > to file_in? This way patch review gets easier, i.e. try avoiding doing > > multiple things per patch. > > the input file needed to be renamed, because new 'output' file was added Why? Is 'file' going to be reused somehow? > > > > > .path = inject->input_name, > > > .mode = PERF_DATA_MODE_READ, > > > }; > > > + struct perf_data_file *file_out = &inject->output; > > > + int out_fd = perf_data_file__fd(file_out); > > > > > > signal(SIGINT, sig_handler); > > > > > > @@ -365,7 +359,7 @@ static int __cmd_inject(struct perf_inject *inject) > > > inject->tool.tracing_data = perf_event__repipe_tracing_data; > > > } > > > > > > - session = perf_session__new(&file, true, &inject->tool); > > > + session = perf_session__new(&file_in, true, &inject->tool); > > > > This hunk, for example, wouldn't be here, the this patch would be > > shorter, easier to review. > > > > > if (session == NULL) > > > return -ENOMEM; > > > > > > @@ -391,14 +385,15 @@ static int __cmd_inject(struct perf_inject *inject) > > > } > > > } > > > > > > - if (!inject->pipe_output) > > > - lseek(inject->output, session->header.data_offset, SEEK_SET); > > > + if (!perf_data_file__is_pipe(file_out)) > > > + lseek(out_fd, session->header.data_offset, SEEK_SET); > > > > Couldn't this be left as: > > > > - if (!inject->pipe_output) > > - lseek(inject->output, session->header.data_offset, SEEK_SET); > > + if (!perf_data_file__is_pipe(file_out)) > > + lseek(inject->output->fd, session->header.data_offset, SEEK_SET); > > > > I.e. why wrap access to the fd like that? > > well, inject->output->fd is used on 2 places within the function, > so it seems logical to put it into variable and use it like that What I'm trying to convey here is that for both this case and the other, having looking at these two lines: - inject->output + inject->output->fd Makes me instantaneously understand that inject->output now encapsulates, among other things (probably), the file descriptor that was called just inject->output, i.e. this patch probably isn't doing anything more than using a new abstraction, the code flow probably wasn't altered. I.e. the smaller the patch, the better. > > > - if (!inject->pipe_output) { > > > + if (!perf_data_file__is_pipe(file_out)) { > > > session->header.data_size = inject->bytes_written; > > > - perf_session__write_header(session, session->evlist, inject->output, true); + perf_session__write_header(session, session->evlist, inject->output->fd, true); > > > > Why a line for 'true' all by itself? > > line was crossing 80 chars limit [1]+ Stopped mutt [acme@zoo ~]$ [acme@zoo ~]$ echo $COLUMNS 173 [acme@zoo ~]$ I'm not really that strict with that old convention :-\ All in one line would make it ~95 columns, not a big deal, even more since it _was_ already more than 80 columns. I.e. your change was to replace 'inject->output' with 'out_fd', but you did that _and_ reflowed, i.e. two changes into one. ;-) Looking at this line makes me think: why do we have to pass 'session' _and_ 'session->evlist', i.e. the 2nd parameter can be obtained from the 1st. Fixing that could get us more compact code _and_ a shorter line. Will check that. > > > - OPT_STRING('o', "output", &output_name, "file", > > > + OPT_STRING('o', "output", &inject.output.path, "file", > > > > see, here you directly access a perf_data_file member instead of having > > another wrapper :-) > > yes > > I dont have strong opinions about wrappers, sometimes it seems > appropriate, sometimes it does not.. tell me the guidance here > and I'll kick the patch to fit ;-) Well, a wrapper like perf_data_file__is_pipe(file_out) that maps to file_out->is_pipe and will produce the same results at every call and that we don't have the slightest intention of somehow hooking, I would do away with it and use file_out->is_pipe directly. - Arnaldo ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] perf inject: Handle output file via perf_data_file object 2013-11-26 12:42 ` Arnaldo Carvalho de Melo @ 2013-11-26 13:07 ` Jiri Olsa 0 siblings, 0 replies; 21+ messages in thread From: Jiri Olsa @ 2013-11-26 13:07 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, David Ahern, Adrian Hunter On Tue, Nov 26, 2013 at 09:42:13AM -0300, Arnaldo Carvalho de Melo wrote: > Em Tue, Nov 26, 2013 at 11:03:24AM +0100, Jiri Olsa escreveu: > > On Mon, Nov 25, 2013 at 04:40:32PM -0300, Arnaldo Carvalho de Melo wrote: > > > Em Fri, Nov 22, 2013 at 03:24:28PM +0100, Jiri Olsa escreveu: > > > > Using the perf_data_file object to handle output > > > SNIP > > > > > + if (!perf_data_file__is_pipe(&inject->output)) > > > > return 0; > > > > > return perf_event__repipe_synth(tool, event); > > > > @@ -351,10 +343,12 @@ static int __cmd_inject(struct perf_inject *inject) > > > > { > > > > struct perf_session *session; > > > > int ret = -EINVAL; > > > > - struct perf_data_file file = { > > > > + struct perf_data_file file_in = { > > > > > > Why don't leave it as 'file', and on a follow up patch _then_ rename it > > > to file_in? This way patch review gets easier, i.e. try avoiding doing > > > multiple things per patch. > > > > the input file needed to be renamed, because new 'output' file was added > > Why? Is 'file' going to be reused somehow? nope, just having file_in and file_out seemed symmetric, but nevermind.. I can switch to file and file_out ;-) SNIP > > > > well, inject->output->fd is used on 2 places within the function, > > so it seems logical to put it into variable and use it like that > > What I'm trying to convey here is that for both this case and the other, > having looking at these two lines: > > - inject->output > + inject->output->fd > > Makes me instantaneously understand that inject->output now > encapsulates, among other things (probably), the file descriptor that > was called just inject->output, i.e. this patch probably isn't doing > anything more than using a new abstraction, the code flow probably > wasn't altered. yes, that's what happened.. encapsulating output file processing and getting rid of common code that's now handled by perf_data_file object.. > > I.e. the smaller the patch, the better. I dont think thats always true.. I prefer readable code despite of 'unreadable' patches ;-) > > > > > - if (!inject->pipe_output) { > > > > + if (!perf_data_file__is_pipe(file_out)) { > > > > session->header.data_size = inject->bytes_written; > > > > - perf_session__write_header(session, session->evlist, inject->output, true); > + perf_session__write_header(session, session->evlist, inject->output->fd, true); > > > > > > Why a line for 'true' all by itself? > > > > line was crossing 80 chars limit > > [1]+ Stopped mutt > [acme@zoo ~]$ > [acme@zoo ~]$ echo $COLUMNS > 173 > [acme@zoo ~]$ > > I'm not really that strict with that old convention :-\ All in one line > would make it ~95 columns, not a big deal, even more since it _was_ > already more than 80 columns. I see.. I'm using checkpatch script that screams about this so I tend to keep to that rule > > I.e. your change was to replace 'inject->output' with 'out_fd', but you > did that _and_ reflowed, i.e. two changes into one. ;-) the smaller the patch, the better, right? :-) > > Looking at this line makes me think: why do we have to pass 'session' > _and_ 'session->evlist', i.e. the 2nd parameter can be obtained from the > 1st. Fixing that could get us more compact code _and_ a shorter line. we do actually, and the reason is this code, because the session keeps the input file, while we are using it for output file.. > > Will check that. > > > > > - OPT_STRING('o', "output", &output_name, "file", > > > > + OPT_STRING('o', "output", &inject.output.path, "file", > > > > > > see, here you directly access a perf_data_file member instead of having > > > another wrapper :-) > > > > yes > > > > I dont have strong opinions about wrappers, sometimes it seems > > appropriate, sometimes it does not.. tell me the guidance here > > and I'll kick the patch to fit ;-) > > Well, a wrapper like perf_data_file__is_pipe(file_out) that maps to > file_out->is_pipe and will produce the same results at every call and > that we don't have the slightest intention of somehow hooking, I would > do away with it and use file_out->is_pipe directly. ok thanks, jirka ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] perf tools: Add data file write interface 2013-11-22 14:24 [PATCH 0/3] perf tools: Add data file write interface Jiri Olsa ` (2 preceding siblings ...) 2013-11-22 14:24 ` [PATCH 3/3] perf inject: Handle output file via perf_data_file object Jiri Olsa @ 2013-11-22 15:01 ` David Ahern 2013-11-23 9:44 ` Jiri Olsa 3 siblings, 1 reply; 21+ messages in thread From: David Ahern @ 2013-11-22 15:01 UTC (permalink / raw) To: Jiri Olsa, linux-kernel Cc: Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, Adrian Hunter On 11/22/13, 7:24 AM, Jiri Olsa wrote: > David, > patch 2 could colide with your mmap changes, not sure > what's your plan with that in near future, let me know > and I can rebase if needed. The day job requires some focus for a few days. I was hoping to revisit the mmap output end of next week during the holidays here. Make mmap optional -- default to write with an option for mmap. Add some builtin detection to do the right thing if the user did not specify a preference -- system wide tracing should flip to mmap, system wide faults should write. Log a warning to the user if the requested option goes against that. If Peter or Ingo have other thoughts or ideas to the contrary I'd love to hear them before the next iteration. David ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] perf tools: Add data file write interface 2013-11-22 15:01 ` [PATCH 0/3] perf tools: Add data file write interface David Ahern @ 2013-11-23 9:44 ` Jiri Olsa 2013-11-24 0:00 ` David Ahern 0 siblings, 1 reply; 21+ messages in thread From: Jiri Olsa @ 2013-11-23 9:44 UTC (permalink / raw) To: David Ahern Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, Adrian Hunter On Fri, Nov 22, 2013 at 08:01:47AM -0700, David Ahern wrote: > On 11/22/13, 7:24 AM, Jiri Olsa wrote: > >David, > >patch 2 could colide with your mmap changes, not sure > >what's your plan with that in near future, let me know > >and I can rebase if needed. > > The day job requires some focus for a few days. I was hoping to > revisit the mmap output end of next week during the holidays here. > Make mmap optional -- default to write with an option for mmap. Add > some builtin detection to do the right thing if the user did not > specify a preference -- system wide tracing should flip to mmap, > system wide faults should write. Log a warning to the user if the > requested option goes against that. If Peter or Ingo have other > thoughts or ideas to the contrary I'd love to hear them before the > next iteration. so.. I understand you'll make changes anyway and dont mind to rebase? ;-) thanks, jirka ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] perf tools: Add data file write interface 2013-11-23 9:44 ` Jiri Olsa @ 2013-11-24 0:00 ` David Ahern 0 siblings, 0 replies; 21+ messages in thread From: David Ahern @ 2013-11-24 0:00 UTC (permalink / raw) To: Jiri Olsa Cc: linux-kernel, Ingo Molnar, Frederic Weisbecker, Peter Zijlstra, Namhyung Kim, Mike Galbraith, Stephane Eranian, Adrian Hunter On 11/23/13, 2:44 AM, Jiri Olsa wrote: > > so.. I understand you'll make changes anyway > and dont mind to rebase? ;-) I can rebase. David ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2013-11-27 15:54 UTC | newest] Thread overview: 21+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-11-22 14:24 [PATCH 0/3] perf tools: Add data file write interface Jiri Olsa 2013-11-22 14:24 ` [PATCH 1/3] perf tools: Add perf_data_file__write interface Jiri Olsa 2013-11-25 19:29 ` Arnaldo Carvalho de Melo 2013-11-26 10:17 ` Jiri Olsa 2013-11-26 17:53 ` [PATCH] tools/perf/util: Document and clean up readn() a bit Ingo Molnar 2013-11-27 8:38 ` Adrian Hunter 2013-11-27 11:57 ` Ingo Molnar 2013-11-27 15:19 ` David Ahern 2013-11-27 15:50 ` Jiri Olsa 2013-11-27 15:54 ` Ingo Molnar 2013-11-22 14:24 ` [PATCH 2/3] perf record: Use perf_data_file__write for output file Jiri Olsa 2013-11-25 19:31 ` Arnaldo Carvalho de Melo 2013-11-26 10:16 ` Jiri Olsa 2013-11-22 14:24 ` [PATCH 3/3] perf inject: Handle output file via perf_data_file object Jiri Olsa 2013-11-25 19:40 ` Arnaldo Carvalho de Melo 2013-11-26 10:03 ` Jiri Olsa 2013-11-26 12:42 ` Arnaldo Carvalho de Melo 2013-11-26 13:07 ` Jiri Olsa 2013-11-22 15:01 ` [PATCH 0/3] perf tools: Add data file write interface David Ahern 2013-11-23 9:44 ` Jiri Olsa 2013-11-24 0:00 ` David Ahern
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox