Read trace files located in data directory into tool process memory. Basic analysis support of data directories is provided for report mode. Raw dump (-D) and aggregated reports are available for data directories, still with no memory consumption optimizations. However data directories collected with --compression-level option enabled can be analyzed with little less memory because trace files are unmaped from tool process memory after loading collected data. The implementation is 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-jo...@kernel.org/ Suggested-by: Jiri Olsa <jo...@kernel.org> Suggested-by: Namhyung Kim <namhy...@kernel.org> Signed-off-by: Alexey Budankov <alexey.budan...@linux.intel.com> --- tools/perf/util/session.c | 48 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/session.h | 1 + 2 files changed, 49 insertions(+) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 6afc670fdf0c..0752eec19813 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -2212,6 +2212,17 @@ reader__process_events(struct reader *rd, struct perf_session *session, goto more; out: + if (rd->unmap_file) { + int i; + + for (i = 0; i < NUM_MMAPS; i++) { + if (mmaps[i]) { + munmap(mmaps[i], mmap_size); + mmaps[i] = NULL; + } + } + } + return err; } @@ -2231,6 +2242,7 @@ static int __perf_session__process_events(struct perf_session *session) .data_offset = session->header.data_offset, .process = process_simple, .path = session->data->file.path, + .unmap_file = false, }; struct ordered_events *oe = &session->ordered_events; struct perf_tool *tool = session->tool; @@ -2247,6 +2259,42 @@ static int __perf_session__process_events(struct perf_session *session) err = reader__process_events(&rd, session, &prog); if (err) goto out_err; + + if (perf_data__is_dir(session->data)) { + int i, nr = session->data->dir.nr; + struct reader file_rd[nr]; + u64 total_size = perf_data__size(session->data); + + total_size -= session->data->file.size; + ui_progress__init_size(&prog, total_size, "Sorting events..."); + + memset(&file_rd, 0, nr * sizeof(file_rd[0])); + + for (i = 0; i < nr ; i++) { + struct perf_data_file *file; + + file = &session->data->dir.files[i]; + file_rd[i] = (struct reader) { + .fd = file->fd, + .path = file->path, + .data_size = file->size, + .data_offset = 0, + .process = process_simple, + }; + file_rd[i].unmap_file = perf_header__has_feat(&session->header, + HEADER_COMPRESSED); + session->reader = &file_rd[i]; + + if (zstd_init(&(file_rd[i].zstd_data), 0)) + goto out_err; + err = reader__process_events(&file_rd[i], session, &prog); + zstd_fini(&(file_rd[i].zstd_data)); + session->reader = NULL; + if (err) + goto out_err; + } + } + /* do the final flush for ordered samples */ err = ordered_events__flush(oe, OE_FLUSH__FINAL); if (err) diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 4fc9ccdf7970..d428f3eaf7fd 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -43,6 +43,7 @@ struct reader { u64 data_offset; reader_cb_t process; struct zstd_data zstd_data; + bool unmap_file; }; struct perf_session { -- 2.24.1