From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751284AbdKUQi6 (ORCPT ); Tue, 21 Nov 2017 11:38:58 -0500 Received: from mail.kernel.org ([198.145.29.99]:48154 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750772AbdKUQi5 (ORCPT ); Tue, 21 Nov 2017 11:38:57 -0500 DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 37A4821985 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=acme@kernel.org Date: Tue, 21 Nov 2017 13:38:54 -0300 From: Arnaldo Carvalho de Melo To: Jin Yao Cc: jolsa@kernel.org, peterz@infradead.org, mingo@redhat.com, alexander.shishkin@linux.intel.com, Linux-kernel@vger.kernel.org, ak@linux.intel.com, kan.liang@intel.com, yao.jin@intel.com Subject: Re: [PATCH v6 1/6] perf header: Record first sample time and last sample time in perf file header Message-ID: <20171121163854.GM7918@kernel.org> References: <1509970871-20996-1-git-send-email-yao.jin@linux.intel.com> <1509970871-20996-2-git-send-email-yao.jin@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1509970871-20996-2-git-send-email-yao.jin@linux.intel.com> X-Url: http://acmel.wordpress.com User-Agent: Mutt/1.9.1 (2017-09-22) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Em Mon, Nov 06, 2017 at 08:21:06PM +0800, Jin Yao escreveu: > perf report/script/... have a --time option to limit the time range > of output. That's very useful to slice large traces, e.g. when processing > the output of perf script for some analysis. > > But right now --time only supports absolute time. Also there is no fast > way to get the start/end times of a given trace except for looking at it. > This makes it hard to e.g. only decode the first half of the trace, which > is useful for parallelization of scripts > > Another problem is that perf records are variable size and there is no > synchronization mechanism. So the only way to find the last sample reliably > would be to walk all samples. But we want to avoid that in perf report/... > because it is already quite expensive. That is why storing the first sample > time and last sample time in perf record is better. > > This patch creates a new header feature type HEADER_SAMPLE_TIME and related > ops. Save the first sample time and the last sample time to the feature > section in perf file header I'll add a clarification here, right after your text: ". That will be done when, for instance, processing build-ids, where we already have to process all samples to create the build-id table, take advantage of that to further amortize that processing by storing HEADER_SAMPLE_TIME to make 'perf report/script' faster when using --time." > > Change log: > ----------- > v4: Use perf script time style for timestamp printing. Also add with > the printing of sample duration. > > v3: Remove the definitions of first_sample_time/last_sample_time from > perf_session. Just define them in perf_evlist > > Signed-off-by: Jin Yao > --- > tools/perf/Documentation/perf.data-file-format.txt | 4 ++ > tools/perf/util/evlist.h | 2 + > tools/perf/util/header.c | 60 ++++++++++++++++++++++ > tools/perf/util/header.h | 1 + > 4 files changed, 67 insertions(+) > > diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt > index e90c59c..d5e3043 100644 > --- a/tools/perf/Documentation/perf.data-file-format.txt > +++ b/tools/perf/Documentation/perf.data-file-format.txt > @@ -238,6 +238,10 @@ struct auxtrace_index { > struct auxtrace_index_entry entries[PERF_AUXTRACE_INDEX_ENTRY_COUNT]; > }; > > + HEADER_SAMPLE_TIME = 21, > + > +Two uint64_t for the time of first sample and the time of last sample. > + > other bits are reserved and should ignored for now > HEADER_FEAT_BITS = 256, > > diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h > index 8c433e9..a08f407 100644 > --- a/tools/perf/util/evlist.h > +++ b/tools/perf/util/evlist.h > @@ -50,6 +50,8 @@ struct perf_evlist { > struct perf_evsel *selected; > struct events_stats stats; > struct perf_env *env; > + u64 first_sample_time; > + u64 last_sample_time; > }; > > struct perf_evsel_str_handler { > diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c > index 6e59dcc..fd81c5b1 100644 > --- a/tools/perf/util/header.c > +++ b/tools/perf/util/header.c > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > > #include "evlist.h" > #include "evsel.h" > @@ -36,6 +37,7 @@ > #include > #include "asm/bug.h" > #include "tool.h" > +#include "time-utils.h" > > #include "sane_ctype.h" > > @@ -1181,6 +1183,20 @@ static int write_stat(struct feat_fd *ff __maybe_unused, > return 0; > } > > +static int write_sample_time(struct feat_fd *ff, > + struct perf_evlist *evlist) > +{ > + int ret; > + > + ret = do_write(ff, &evlist->first_sample_time, > + sizeof(evlist->first_sample_time)); > + if (ret < 0) > + return ret; > + > + return do_write(ff, &evlist->last_sample_time, > + sizeof(evlist->last_sample_time)); > +} > + > static void print_hostname(struct feat_fd *ff, FILE *fp) > { > fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname); > @@ -1506,6 +1522,28 @@ static void print_group_desc(struct feat_fd *ff, FILE *fp) > } > } > > +static void print_sample_time(struct feat_fd *ff, FILE *fp) > +{ > + struct perf_session *session; > + char time_buf[32]; > + double d; > + > + session = container_of(ff->ph, struct perf_session, header); > + > + timestamp__scnprintf_usec(session->evlist->first_sample_time, > + time_buf, sizeof(time_buf)); > + fprintf(fp, "# time of first sample : %s\n", time_buf); > + > + timestamp__scnprintf_usec(session->evlist->last_sample_time, > + time_buf, sizeof(time_buf)); > + fprintf(fp, "# time of last sample : %s\n", time_buf); > + > + d = (double)(session->evlist->last_sample_time - > + session->evlist->first_sample_time) / NSEC_PER_MSEC; > + > + fprintf(fp, "# sample duration : %10.3f ms\n", d); > +} > + > static int __event_process_build_id(struct build_id_event *bev, > char *filename, > struct perf_session *session) > @@ -2147,6 +2185,27 @@ static int process_cache(struct feat_fd *ff, void *data __maybe_unused) > return -1; > } > > +static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused) > +{ > + struct perf_session *session; > + u64 first_sample_time, last_sample_time; > + int ret; > + > + session = container_of(ff->ph, struct perf_session, header); > + > + ret = do_read_u64(ff, &first_sample_time); > + if (ret) > + return -1; > + > + ret = do_read_u64(ff, &last_sample_time); > + if (ret) > + return -1; > + > + session->evlist->first_sample_time = first_sample_time; > + session->evlist->last_sample_time = last_sample_time; > + return 0; > +} > + > struct feature_ops { > int (*write)(struct feat_fd *ff, struct perf_evlist *evlist); > void (*print)(struct feat_fd *ff, FILE *fp); > @@ -2204,6 +2263,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { > FEAT_OPN(AUXTRACE, auxtrace, false), > FEAT_OPN(STAT, stat, false), > FEAT_OPN(CACHE, cache, true), > + FEAT_OPR(SAMPLE_TIME, sample_time, false), > }; > > struct header_print_data { > diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h > index f7a16ee..1911831 100644 > --- a/tools/perf/util/header.h > +++ b/tools/perf/util/header.h > @@ -33,6 +33,7 @@ enum { > HEADER_AUXTRACE, > HEADER_STAT, > HEADER_CACHE, > + HEADER_SAMPLE_TIME, > HEADER_LAST_FEATURE, > HEADER_FEAT_BITS = 256, > }; > -- > 2.7.4