2021-05-26 10:57:43

by Bayduraev, Alexey V

[permalink] [raw]
Subject: [PATCH v6 16/20] perf session: Introduce decompressor into trace reader object

Introduce decompressor into trace reader object so that decompression
could be executed on per data file basis separately for every data
file located in data directory.

Signed-off-by: Alexey Bayduraev <[email protected]>
---
tools/perf/util/session.c | 51 +++++++++++++++++++++++++++++----------
tools/perf/util/session.h | 1 +
2 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 335c073bae87..6c9a682eb291 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -73,6 +73,9 @@ struct reader {
u64 data_offset;
reader_cb_t process;
bool in_place_update;
+ struct zstd_data zstd_data;
+ struct decomp *decomp;
+ struct decomp *decomp_last;
struct reader_state state;
};

@@ -85,7 +88,10 @@ static int perf_session__process_compressed_event(struct perf_session *session,
size_t decomp_size, src_size;
u64 decomp_last_rem = 0;
size_t mmap_len, decomp_len = session->header.env.comp_mmap_len;
- struct decomp *decomp, *decomp_last = session->decomp_last;
+ struct decomp *decomp, *decomp_last = session->active_reader ?
+ session->active_reader->decomp_last : session->decomp_last;
+ struct zstd_data *zstd_data = session->active_reader ?
+ &session->active_reader->zstd_data : &session->zstd_data;

if (decomp_last) {
decomp_last_rem = decomp_last->size - decomp_last->head;
@@ -113,7 +119,7 @@ static int perf_session__process_compressed_event(struct perf_session *session,
src = (void *)event + sizeof(struct perf_record_compressed);
src_size = event->pack.header.size - sizeof(struct perf_record_compressed);

- decomp_size = zstd_decompress_stream(&(session->zstd_data), src, src_size,
+ decomp_size = zstd_decompress_stream(zstd_data, src, src_size,
&(decomp->data[decomp_last_rem]), decomp_len - decomp_last_rem);
if (!decomp_size) {
munmap(decomp, mmap_len);
@@ -123,12 +129,22 @@ static int perf_session__process_compressed_event(struct perf_session *session,

decomp->size += decomp_size;

- if (session->decomp == NULL) {
- session->decomp = decomp;
- session->decomp_last = decomp;
+ if (session->active_reader) {
+ if (session->active_reader->decomp == NULL) {
+ session->active_reader->decomp = decomp;
+ session->active_reader->decomp_last = decomp;
+ } else {
+ session->active_reader->decomp_last->next = decomp;
+ session->active_reader->decomp_last = decomp;
+ }
} else {
- session->decomp_last->next = decomp;
- session->decomp_last = decomp;
+ if (session->decomp == NULL) {
+ session->decomp = decomp;
+ session->decomp_last = decomp;
+ } else {
+ session->decomp_last->next = decomp;
+ session->decomp_last = decomp;
+ }
}

pr_debug("decomp (B): %zd to %zd\n", src_size, decomp_size);
@@ -319,11 +335,10 @@ static void perf_session__delete_threads(struct perf_session *session)
machine__delete_threads(&session->machines.host);
}

-static void perf_session__release_decomp_events(struct perf_session *session)
+static void perf_decomp__release_events(struct decomp *next)
{
- struct decomp *next, *decomp;
+ struct decomp *decomp;
size_t mmap_len;
- next = session->decomp;
do {
decomp = next;
if (decomp == NULL)
@@ -336,6 +351,8 @@ static void perf_session__release_decomp_events(struct perf_session *session)

void perf_session__delete(struct perf_session *session)
{
+ int r;
+
if (session == NULL)
return;
auxtrace__free(session);
@@ -343,10 +360,12 @@ void perf_session__delete(struct perf_session *session)
perf_session__destroy_kernel_maps(session);
perf_session__delete_threads(session);
if (session->readers) {
+ for (r = 0; r < session->nr_readers; r++)
+ perf_decomp__release_events(session->readers[r].decomp);
zfree(&session->readers);
session->nr_readers = 0;
}
- perf_session__release_decomp_events(session);
+ perf_decomp__release_events(session->decomp);
perf_env__exit(&session->header.env);
machines__exit(&session->machines);
if (session->data)
@@ -2157,7 +2176,8 @@ static int __perf_session__process_decomp_events(struct perf_session *session)
{
s64 skip;
u64 size;
- struct decomp *decomp = session->decomp_last;
+ struct decomp *decomp = session->active_reader ?
+ session->active_reader->decomp_last : session->decomp_last;

if (!decomp)
return 0;
@@ -2214,6 +2234,9 @@ reader__process_events(struct reader *rd, struct perf_session *session,

memset(mmaps, 0, sizeof(st->mmaps));

+ if (zstd_init(&rd->zstd_data, 0))
+ return -1;
+
mmap_prot = PROT_READ;
mmap_flags = MAP_SHARED;

@@ -2257,12 +2280,13 @@ reader__process_events(struct reader *rd, struct perf_session *session,
goto remap;
}

+ session->active_reader = rd;
size = event->header.size;

skip = -EINVAL;

if (size < sizeof(struct perf_event_header) ||
- (skip = rd->process(session, event, st->file_pos, rd->path)) < 0) {
+ (skip = perf_session__process_event(session, event, st->file_pos, rd->path)) < 0) {
pr_err("%#" PRIx64 " [%s] [%#x]: failed to process type: %d [%s]\n",
st->file_offset + st->head, rd->path, event->header.size,
event->header.type, strerror(-skip));
@@ -2289,6 +2313,7 @@ reader__process_events(struct reader *rd, struct perf_session *session,
goto more;

out:
+ session->active_reader = NULL;
return err;
}

diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 2815d00b5467..e0a8712f8770 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -44,6 +44,7 @@ struct perf_session {
struct decomp *decomp_last;
struct reader *readers;
int nr_readers;
+ struct reader *active_reader;
};

struct decomp {
--
2.19.0


2021-06-03 23:26:53

by Riccardo Mancini

[permalink] [raw]
Subject: Re: [PATCH v6 16/20] perf session: Introduce decompressor into trace reader object

Hi,

On Wed, 2021-05-26 at 13:53 +0300, Alexey Bayduraev wrote:
> Introduce decompressor into trace reader object so that decompression
> could be executed on per data file basis separately for every data
> file located in data directory.
>
> Signed-off-by: Alexey Bayduraev <[email protected]>
> ---
>  tools/perf/util/session.c | 51 +++++++++++++++++++++++++++++----------
>  tools/perf/util/session.h |  1 +
>  2 files changed, 39 insertions(+), 13 deletions(-)
>
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 335c073bae87..6c9a682eb291 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -73,6 +73,9 @@ struct reader {
>         u64              data_offset;
>         reader_cb_t      process;
>         bool             in_place_update;
> +       struct zstd_data zstd_data;
> +       struct decomp    *decomp;
> +       struct decomp    *decomp_last;
>         struct reader_state state;
>  };
>  
> @@ -85,7 +88,10 @@ static int perf_session__process_compressed_event(struct
> perf_session *session,
>         size_t decomp_size, src_size;
>         u64 decomp_last_rem = 0;
>         size_t mmap_len, decomp_len = session->header.env.comp_mmap_len;
> -       struct decomp *decomp, *decomp_last = session->decomp_last;
> +       struct decomp *decomp, *decomp_last = session->active_reader ?
> +               session->active_reader->decomp_last : session->decomp_last;
> +       struct zstd_data *zstd_data = session->active_reader ?
> +               &session->active_reader->zstd_data : &session->zstd_data;
>  
>         if (decomp_last) {
>                 decomp_last_rem = decomp_last->size - decomp_last->head;
> @@ -113,7 +119,7 @@ static int perf_session__process_compressed_event(struct
> perf_session *session,
>         src = (void *)event + sizeof(struct perf_record_compressed);
>         src_size = event->pack.header.size - sizeof(struct
> perf_record_compressed);
>  
> -       decomp_size = zstd_decompress_stream(&(session->zstd_data), src,
> src_size,
> +       decomp_size = zstd_decompress_stream(zstd_data, src, src_size,
>                                 &(decomp->data[decomp_last_rem]), decomp_len -
> decomp_last_rem);
>         if (!decomp_size) {
>                 munmap(decomp, mmap_len);
> @@ -123,12 +129,22 @@ static int perf_session__process_compressed_event(struct
> perf_session *session,
>  
>         decomp->size += decomp_size;
>  
> -       if (session->decomp == NULL) {
> -               session->decomp = decomp;
> -               session->decomp_last = decomp;
> +       if (session->active_reader) {
> +               if (session->active_reader->decomp == NULL) {
> +                       session->active_reader->decomp = decomp;
> +                       session->active_reader->decomp_last = decomp;
> +               } else {
> +                       session->active_reader->decomp_last->next = decomp;
> +                       session->active_reader->decomp_last = decomp;
> +               }
>         } else {
> -               session->decomp_last->next = decomp;
> -               session->decomp_last = decomp;
> +               if (session->decomp == NULL) {
> +                       session->decomp = decomp;
> +                       session->decomp_last = decomp;
> +               } else {
> +                       session->decomp_last->next = decomp;
> +                       session->decomp_last = decomp;
> +               }
>         }
>  
>         pr_debug("decomp (B): %zd to %zd\n", src_size, decomp_size);
> @@ -319,11 +335,10 @@ static void perf_session__delete_threads(struct
> perf_session *session)
>         machine__delete_threads(&session->machines.host);
>  }
>  
> -static void perf_session__release_decomp_events(struct perf_session *session)
> +static void perf_decomp__release_events(struct decomp *next)
>  {
> -       struct decomp *next, *decomp;
> +       struct decomp *decomp;
>         size_t mmap_len;
> -       next = session->decomp;
>         do {
>                 decomp = next;
>                 if (decomp == NULL)
> @@ -336,6 +351,8 @@ static void perf_session__release_decomp_events(struct
> perf_session *session)
>  
>  void perf_session__delete(struct perf_session *session)
>  {
> +       int r;
> +
>         if (session == NULL)
>                 return;
>         auxtrace__free(session);
> @@ -343,10 +360,12 @@ void perf_session__delete(struct perf_session *session)
>         perf_session__destroy_kernel_maps(session);
>         perf_session__delete_threads(session);
>         if (session->readers) {
> +               for (r = 0; r < session->nr_readers; r++)
> +                       perf_decomp__release_events(session-
> >readers[r].decomp);
>                 zfree(&session->readers);
>                 session->nr_readers = 0;
>         }
> -       perf_session__release_decomp_events(session);
> +       perf_decomp__release_events(session->decomp);
>         perf_env__exit(&session->header.env);
>         machines__exit(&session->machines);
>         if (session->data)
> @@ -2157,7 +2176,8 @@ static int __perf_session__process_decomp_events(struct
> perf_session *session)
>  {
>         s64 skip;
>         u64 size;
> -       struct decomp *decomp = session->decomp_last;
> +       struct decomp *decomp = session->active_reader ?
> +               session->active_reader->decomp_last : session->decomp_last;
>  
>         if (!decomp)
>                 return 0;
> @@ -2214,6 +2234,9 @@ reader__process_events(struct reader *rd, struct
> perf_session *session,
>  
>         memset(mmaps, 0, sizeof(st->mmaps));
>  
> +       if (zstd_init(&rd->zstd_data, 0))
> +               return -1;
> +
>         mmap_prot  = PROT_READ;
>         mmap_flags = MAP_SHARED;

zstd_fini is never called on zstd_data.

Thanks,
Riccardo

> @@ -2257,12 +2280,13 @@ reader__process_events(struct reader *rd, struct
> perf_session *session,
>                 goto remap;
>         }
>  
> +       session->active_reader = rd;
>         size = event->header.size;
>  
>         skip = -EINVAL;
>  
>         if (size < sizeof(struct perf_event_header) ||
> -           (skip = rd->process(session, event, st->file_pos, rd->path)) < 0)
> {
> +           (skip = perf_session__process_event(session, event, st->file_pos,
> rd->path)) < 0) {
>                 pr_err("%#" PRIx64 " [%s] [%#x]: failed to process type: %d
> [%s]\n",
>                        st->file_offset + st->head, rd->path, event-
> >header.size,
>                        event->header.type, strerror(-skip));
> @@ -2289,6 +2313,7 @@ reader__process_events(struct reader *rd, struct
> perf_session *session,
>                 goto more;
>  
>  out:
> +       session->active_reader = NULL;
>         return err;
>  }
>  
> diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
> index 2815d00b5467..e0a8712f8770 100644
> --- a/tools/perf/util/session.h
> +++ b/tools/perf/util/session.h
> @@ -44,6 +44,7 @@ struct perf_session {
>         struct decomp           *decomp_last;
>         struct reader           *readers;
>         int                     nr_readers;
> +       struct reader           *active_reader;
>  };
>  
>  struct decomp {