Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FE2FC433F5 for ; Tue, 23 Nov 2021 14:09:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233072AbhKWOMh (ORCPT ); Tue, 23 Nov 2021 09:12:37 -0500 Received: from mga06.intel.com ([134.134.136.31]:59350 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235904AbhKWOMJ (ORCPT ); Tue, 23 Nov 2021 09:12:09 -0500 X-IronPort-AV: E=McAfee;i="6200,9189,10176"; a="295833842" X-IronPort-AV: E=Sophos;i="5.87,257,1631602800"; d="scan'208";a="295833842" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Nov 2021 06:09:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,257,1631602800"; d="scan'208";a="509422527" Received: from nntpat99-84.inn.intel.com ([10.125.99.84]) by orsmga008.jf.intel.com with ESMTP; 23 Nov 2021 06:08:55 -0800 From: Alexey Bayduraev To: Arnaldo Carvalho de Melo Cc: Jiri Olsa , Namhyung Kim , Alexander Shishkin , Peter Zijlstra , Ingo Molnar , linux-kernel , Andi Kleen , Adrian Hunter , Alexander Antonov , Alexei Budankov , Riccardo Mancini Subject: [PATCH v12 08/16] perf record: Introduce data file at mmap buffer object Date: Tue, 23 Nov 2021 17:08:04 +0300 Message-Id: <06c298ce2f2f05964fb507524e1eb7080d57da4b.1637675515.git.alexey.v.bayduraev@linux.intel.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Introduce data file objects into mmap object so it could be used to process and store data stream from the corresponding kernel data buffer. Initialize data files located at mmap buffer objects so trace data can be written into several data file located at data directory. Acked-by: Andi Kleen Acked-by: Namhyung Kim Signed-off-by: Alexey Bayduraev --- tools/perf/builtin-record.c | 46 +++++++++++++++++++++++++++++++------ tools/perf/util/mmap.h | 1 + tools/perf/util/record.h | 1 + 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f054e2106ef9..ce660691df1d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -167,6 +167,11 @@ static inline pid_t gettid(void) } #endif +static int record__threads_enabled(struct record *rec) +{ + return rec->opts.threads_spec; +} + static bool switch_output_signal(struct record *rec) { return rec->switch_output.signal && @@ -197,12 +202,16 @@ static int record__write(struct record *rec, struct mmap *map __maybe_unused, { struct perf_data_file *file = &rec->session->data->file; + if (map && map->file) + file = map->file; + if (perf_data_file__write(file, bf, size) < 0) { pr_err("failed to write perf data, error: %m\n"); return -1; } - rec->bytes_written += size; + if (!(map && map->file)) + rec->bytes_written += size; if (record__output_max_size_exceeded(rec) && !done) { fprintf(stderr, "[ perf record: perf size limit reached (%" PRIu64 " KB)," @@ -1102,7 +1111,7 @@ static int record__alloc_thread_data(struct record *rec, struct evlist *evlist) static int record__mmap_evlist(struct record *rec, struct evlist *evlist) { - int ret; + int i, ret; struct record_opts *opts = &rec->opts; bool auxtrace_overwrite = opts->auxtrace_snapshot_mode || opts->auxtrace_sample_mode; @@ -1141,6 +1150,18 @@ static int record__mmap_evlist(struct record *rec, if (ret) return ret; + if (record__threads_enabled(rec)) { + ret = perf_data__create_dir(&rec->data, evlist->core.nr_mmaps); + if (ret) + return ret; + for (i = 0; i < evlist->core.nr_mmaps; i++) { + if (evlist->mmap) + evlist->mmap[i].file = &rec->data.dir.files[i]; + if (evlist->overwrite_mmap) + evlist->overwrite_mmap[i].file = &rec->data.dir.files[i]; + } + } + return 0; } @@ -1447,8 +1468,12 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist, /* * Mark the round finished in case we wrote * at least one event. + * + * No need for round events in directory mode, + * because per-cpu maps and files have data + * sorted by kernel. */ - if (bytes_written != rec->bytes_written) + if (!record__threads_enabled(rec) && bytes_written != rec->bytes_written) rc = record__write(rec, NULL, &finished_round_event, sizeof(finished_round_event)); if (overwrite) @@ -1564,7 +1589,9 @@ static void record__init_features(struct record *rec) if (!rec->opts.use_clockid) perf_header__clear_feat(&session->header, HEADER_CLOCK_DATA); - perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT); + if (!record__threads_enabled(rec)) + perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT); + if (!record__comp_enabled(rec)) perf_header__clear_feat(&session->header, HEADER_COMPRESSED); @@ -1574,6 +1601,7 @@ static void record__init_features(struct record *rec) static void record__finish_output(struct record *rec) { + int i; struct perf_data *data = &rec->data; int fd = perf_data__fd(data); @@ -1582,8 +1610,14 @@ record__finish_output(struct record *rec) rec->session->header.data_size += rec->bytes_written; data->file.size = lseek(perf_data__fd(data), 0, SEEK_CUR); + if (record__threads_enabled(rec)) { + for (i = 0; i < data->dir.nr; i++) + data->dir.files[i].size = lseek(data->dir.files[i].fd, 0, SEEK_CUR); + } if (!rec->no_buildid) { + /* this will be recalculated during process_buildids() */ + rec->samples = 0; process_buildids(rec); if (rec->buildid_all) @@ -2490,8 +2524,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) status = err; record__synthesize(rec, true); - /* this will be recalculated during process_buildids() */ - rec->samples = 0; if (!err) { if (!rec->timestamp_filename) { @@ -3312,7 +3344,7 @@ int cmd_record(int argc, const char **argv) goto out_opts; } - if (rec->opts.kcore) + if (rec->opts.kcore || record__threads_enabled(rec)) rec->data.is_dir = true; if (rec->opts.comp_level != 0) { diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index 8e259b9610f8..a3370a8bf307 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -44,6 +44,7 @@ struct mmap { struct mmap_cpu_mask affinity_mask; void *data; int comp_level; + struct perf_data_file *file; }; struct mmap_params { diff --git a/tools/perf/util/record.h b/tools/perf/util/record.h index ef6c2715fdd9..ad08c092f3dd 100644 --- a/tools/perf/util/record.h +++ b/tools/perf/util/record.h @@ -78,6 +78,7 @@ struct record_opts { int ctl_fd_ack; bool ctl_fd_close; int synth; + int threads_spec; }; extern const char * const *record_usage; -- 2.19.0