Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp1507904pxv; Fri, 2 Jul 2021 05:38:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz2TGjHR0I38fbXkmbJiiG/mtKQC4M0rY0U2MWuT8AqWR4fyE9YD4ziL7Wh41EIroKWBwGt X-Received: by 2002:a17:907:c02:: with SMTP id ga2mr5029612ejc.215.1625229507412; Fri, 02 Jul 2021 05:38:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625229507; cv=none; d=google.com; s=arc-20160816; b=XFH+ZS33spV6Q/K72BqGtthcg3DxIE6Aus4E8zrGRt6vL2ZEeH+KZTD9EUW9NZrHRP UxeE8GorIwjCGZwwRGmmC2fdpzhA6fvFrTFsD1ATHl76/V0ZubLsgHIKC+YGvsjz0/hW XMWrWf/eE87xhvOzR3UYfHCiuaI/bMPYZITj4MUMH4v84c6Nc/wooCNL8Nmg5q8pgtjt pjeBztBT/633arWWYh7hZgCZWWhHhBh2xXRMoCstsX4sG6wg64DCaP04iM3Cy7zqT3lM e/B0f0a0ZA7SOxfEBqluvCDNV/HnAuXRVzvRtDUD9Y4+R7UcH69x2UV6rNQdB2o2ZCbe OdJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=zq+AVJKIcXqXJAdSvQkTbNrhRZxs/H4Ysaw/pl9PyUo=; b=FJqYvb4VBqYhDxekJr4POrsYLElU41zlFacNmnLKDnlbuBejbOKKyct4HAgW+1EjJs aDzTDkigJTxIzzhDCjdEE5G8JOyYhBlM8T2ZYV2/q/tFEeuPFkF44yIU6FDV0jzwLzKK 1SVObVBLN7XdmUOuWSewn141J1UI4F8KsfNNC3hFsDJm2/QaEvIDw5cXlY8UMlUhy12O wNLNYQ7vRA8JY66RUZG3lpAkrwN20L9SDooEv4+Rvj0m5EBwA0D2gGt/IToIx533ZJha ZBjN9LwVspgcFitVQe+XsIUNiaXTjZ44Tf7lJHTjxPURX20REWD1G4BT5NzJ82sc3vpI 6J2w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g19si2963490edb.164.2021.07.02.05.38.04; Fri, 02 Jul 2021 05:38:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232556AbhGBMgZ (ORCPT + 99 others); Fri, 2 Jul 2021 08:36:25 -0400 Received: from mga17.intel.com ([192.55.52.151]:32637 "EHLO mga17.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232554AbhGBMgW (ORCPT ); Fri, 2 Jul 2021 08:36:22 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10032"; a="189107363" X-IronPort-AV: E=Sophos;i="5.83,317,1616482800"; d="scan'208";a="189107363" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jul 2021 05:33:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,317,1616482800"; d="scan'208";a="642660379" Received: from nntpat99-84.inn.intel.com ([10.125.99.84]) by fmsmga006.fm.intel.com with ESMTP; 02 Jul 2021 05:33:47 -0700 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 v9 24/24] perf session: Load data directory files for analysis Date: Fri, 2 Jul 2021 15:32:32 +0300 Message-Id: <4fd68fdcce3c40d6d48b171eb2c8ae4f43423956.1625227739.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 Load data directory files and provide basic raw dump and aggregated analysis support of data directories in report mode, still with no memory consumption optimizations. Design and implementation are based on the prototype [1], [2]. [1] git clone https://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git -b perf/record_threads [2] https://lore.kernel.org/lkml/20180913125450.21342-1-jolsa@kernel.org/ Suggested-by: Jiri Olsa Acked-by: Namhyung Kim Signed-off-by: Alexey Bayduraev --- tools/perf/util/session.c | 131 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 63811fec2583..021f543c22a4 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -48,6 +48,13 @@ #define NUM_MMAPS 128 #endif +/* + * Processing 10MBs of data from each reader in sequence, + * because that's the way the ordered events sorting works + * most efficiently. + */ +#define READER_MAX_SIZE (10 * 1024 * 1024) + struct reader; typedef s64 (*reader_cb_t)(struct perf_session *session, @@ -65,6 +72,7 @@ struct reader_state { u64 data_size; u64 head; bool eof; + u64 size; }; enum { @@ -2326,6 +2334,7 @@ reader__read_event(struct reader *rd, struct perf_session *session, if (skip) size += skip; + st->size += size; st->head += size; st->file_pos += size; @@ -2425,6 +2434,125 @@ static int __perf_session__process_events(struct perf_session *session) return err; } +/* + * This function reads, merge and process directory data. + * It assumens the version 1 of directory data, where each + * data file holds per-cpu data, already sorted by kernel. + */ +static int __perf_session__process_dir_events(struct perf_session *session) +{ + struct perf_data *data = session->data; + struct perf_tool *tool = session->tool; + int i, ret = 0, readers = 1; + struct ui_progress prog; + u64 total_size = perf_data__size(session->data); + struct reader *rd; + + perf_tool__fill_defaults(tool); + + ui_progress__init_size(&prog, total_size, "Sorting events..."); + + for (i = 0; i < data->dir.nr; i++) { + if (data->dir.files[i].size) + readers++; + } + + rd = session->readers = zalloc(readers * sizeof(struct reader)); + if (!rd) + return -ENOMEM; + session->nr_readers = readers; + readers = 0; + + rd[readers] = (struct reader) { + .fd = perf_data__fd(session->data), + .path = session->data->file.path, + .data_size = session->header.data_size, + .data_offset = session->header.data_offset, + .in_place_update = session->data->in_place_update, + }; + ret = reader__init(&rd[readers], NULL); + if (ret) + goto out_err; + ret = reader__mmap(&rd[readers], session); + if (ret != READER_OK) { + if (ret == READER_EOF) + ret = -EINVAL; + goto out_err; + } + readers++; + + for (i = 0; i < data->dir.nr; i++) { + if (!data->dir.files[i].size) + continue; + rd[readers] = (struct reader) { + .fd = data->dir.files[i].fd, + .path = data->dir.files[i].path, + .data_size = data->dir.files[i].size, + .data_offset = 0, + .in_place_update = session->data->in_place_update, + }; + ret = reader__init(&rd[readers], NULL); + if (ret) + goto out_err; + ret = reader__mmap(&rd[readers], session); + if (ret != READER_OK) { + if (ret == READER_EOF) + ret = -EINVAL; + goto out_err; + } + readers++; + } + + i = 0; + + while ((ret >= 0) && readers) { + if (session_done()) + return 0; + + if (rd[i].state.eof) { + i = (i + 1) % session->nr_readers; + continue; + } + + ret = reader__read_event(&rd[i], session, &prog); + if (ret < 0) + break; + if (ret == READER_NODATA) { + ret = reader__mmap(&rd[i], session); + if (ret < 0) + goto out_err; + if (ret == READER_EOF) + readers--; + } + + if (rd[i].state.size >= READER_MAX_SIZE) { + rd[i].state.size = 0; + i = (i + 1) % session->nr_readers; + } + } + + ret = ordered_events__flush(&session->ordered_events, OE_FLUSH__FINAL); + if (ret) + goto out_err; + + ret = perf_session__flush_thread_stacks(session); +out_err: + ui_progress__finish(); + + if (!tool->no_warn) + perf_session__warn_about_errors(session); + + /* + * We may switching perf.data output, make ordered_events + * reusable. + */ + ordered_events__reinit(&session->ordered_events); + + session->one_mmap = false; + + return ret; +} + int perf_session__process_events(struct perf_session *session) { if (perf_session__register_idle_thread(session) < 0) @@ -2433,6 +2561,9 @@ int perf_session__process_events(struct perf_session *session) if (perf_data__is_pipe(session->data)) return __perf_session__process_pipe_events(session); + if (perf_data__is_dir(session->data)) + return __perf_session__process_dir_events(session); + return __perf_session__process_events(session); } -- 2.19.0