[PATCH 08/37] perf tools: Handle multi-file session properly

From: Namhyung Kim
Date: Wed Dec 24 2014 - 02:24:10 EST


When perf detects multi-file data directory, process header file first
and then rest data files in a row. Note that the multi-file data is
recorded for each cpu/thread separately, it's already ordered with
respect to themselves so no need to use the ordered event queue
interface.

Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
---
tools/perf/util/data.c | 17 +++++++++++++++++
tools/perf/util/session.c | 41 +++++++++++++++++++++++++++++++----------
2 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index 8dacd34659cc..b6f7cdc4a39f 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -52,6 +52,21 @@ static int check_backup(struct perf_data_file *file)
return 0;
}

+static void check_multi(struct perf_data_file *file)
+{
+ struct stat st;
+
+ /*
+ * For write, it'll be determined by user (perf record -M)
+ * whether to enable multi file data storage.
+ */
+ if (perf_data_file__is_write(file))
+ return;
+
+ if (!stat(file->path, &st) && S_ISDIR(st.st_mode))
+ file->is_multi = true;
+}
+
static int scandir_filter(const struct dirent *d)
{
return !prefixcmp(d->d_name, "perf.data.");
@@ -206,6 +221,8 @@ int perf_data_file__open(struct perf_data_file *file)
if (check_pipe(file))
return 0;

+ check_multi(file);
+
if (!file->path)
file->path = default_data_path(file);

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 88aa2f09df93..4f0fcd2d3901 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1252,11 +1252,10 @@ fetch_mmaped_event(struct perf_session *session,
#define NUM_MMAPS 128
#endif

-static int __perf_session__process_events(struct perf_session *session,
+static int __perf_session__process_events(struct perf_session *session, int fd,
u64 data_offset, u64 data_size,
u64 file_size, struct perf_tool *tool)
{
- int fd = perf_data_file__fd(session->file);
u64 head, page_offset, file_offset, file_pos, size;
int err, mmap_prot, mmap_flags, map_idx = 0;
size_t mmap_size;
@@ -1362,18 +1361,40 @@ int perf_session__process_events(struct perf_session *session,
struct perf_tool *tool)
{
u64 size = perf_data_file__size(session->file);
- int err;
+ int err, i;

if (perf_session__register_idle_thread(session) == NULL)
return -ENOMEM;

- if (!perf_data_file__is_pipe(session->file))
- err = __perf_session__process_events(session,
- session->header.data_offset,
- session->header.data_size,
- size, tool);
- else
- err = __perf_session__process_pipe_events(session, tool);
+ if (perf_data_file__is_pipe(session->file))
+ return __perf_session__process_pipe_events(session, tool);
+
+ err = __perf_session__process_events(session,
+ perf_data_file__fd(session->file),
+ session->header.data_offset,
+ session->header.data_size,
+ size, tool);
+ if (!session->file->is_multi || err)
+ return err;
+
+ /*
+ * For multi-file data storage, events are processed for each
+ * cpu/thread so it's already ordered.
+ */
+ tool->ordered_events = false;
+
+ for (i = 0; i < session->file->nr_multi; i++) {
+ int fd = perf_data_file__multi_fd(session->file, i);
+
+ size = lseek(fd, 0, SEEK_END);
+ if (size == 0)
+ continue;
+
+ err = __perf_session__process_events(session, fd,
+ 0, size, size, tool);
+ if (err < 0)
+ break;
+ }

return err;
}
--
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/