aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c116
1 files changed, 115 insertions, 1 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ec1dec86d0e1..2310a1752983 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -29,6 +29,61 @@
29#include "stat.h" 29#include "stat.h"
30#include "arch/common.h" 30#include "arch/common.h"
31 31
32#ifdef HAVE_ZSTD_SUPPORT
33static int perf_session__process_compressed_event(struct perf_session *session,
34 union perf_event *event, u64 file_offset)
35{
36 void *src;
37 size_t decomp_size, src_size;
38 u64 decomp_last_rem = 0;
39 size_t decomp_len = session->header.env.comp_mmap_len;
40 struct decomp *decomp, *decomp_last = session->decomp_last;
41
42 decomp = mmap(NULL, sizeof(struct decomp) + decomp_len, PROT_READ|PROT_WRITE,
43 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
44 if (decomp == MAP_FAILED) {
45 pr_err("Couldn't allocate memory for decompression\n");
46 return -1;
47 }
48
49 decomp->file_pos = file_offset;
50 decomp->head = 0;
51
52 if (decomp_last) {
53 decomp_last_rem = decomp_last->size - decomp_last->head;
54 memcpy(decomp->data, &(decomp_last->data[decomp_last->head]), decomp_last_rem);
55 decomp->size = decomp_last_rem;
56 }
57
58 src = (void *)event + sizeof(struct compressed_event);
59 src_size = event->pack.header.size - sizeof(struct compressed_event);
60
61 decomp_size = zstd_decompress_stream(&(session->zstd_data), src, src_size,
62 &(decomp->data[decomp_last_rem]), decomp_len - decomp_last_rem);
63 if (!decomp_size) {
64 munmap(decomp, sizeof(struct decomp) + decomp_len);
65 pr_err("Couldn't decompress data\n");
66 return -1;
67 }
68
69 decomp->size += decomp_size;
70
71 if (session->decomp == NULL) {
72 session->decomp = decomp;
73 session->decomp_last = decomp;
74 } else {
75 session->decomp_last->next = decomp;
76 session->decomp_last = decomp;
77 }
78
79 pr_debug("decomp (B): %ld to %ld\n", src_size, decomp_size);
80
81 return 0;
82}
83#else /* !HAVE_ZSTD_SUPPORT */
84#define perf_session__process_compressed_event perf_session__process_compressed_event_stub
85#endif
86
32static int perf_session__deliver_event(struct perf_session *session, 87static int perf_session__deliver_event(struct perf_session *session,
33 union perf_event *event, 88 union perf_event *event,
34 struct perf_tool *tool, 89 struct perf_tool *tool,
@@ -197,6 +252,21 @@ static void perf_session__delete_threads(struct perf_session *session)
197 machine__delete_threads(&session->machines.host); 252 machine__delete_threads(&session->machines.host);
198} 253}
199 254
255static void perf_session__release_decomp_events(struct perf_session *session)
256{
257 struct decomp *next, *decomp;
258 size_t decomp_len;
259 next = session->decomp;
260 decomp_len = session->header.env.comp_mmap_len;
261 do {
262 decomp = next;
263 if (decomp == NULL)
264 break;
265 next = decomp->next;
266 munmap(decomp, decomp_len + sizeof(struct decomp));
267 } while (1);
268}
269
200void perf_session__delete(struct perf_session *session) 270void perf_session__delete(struct perf_session *session)
201{ 271{
202 if (session == NULL) 272 if (session == NULL)
@@ -205,6 +275,7 @@ void perf_session__delete(struct perf_session *session)
205 auxtrace_index__free(&session->auxtrace_index); 275 auxtrace_index__free(&session->auxtrace_index);
206 perf_session__destroy_kernel_maps(session); 276 perf_session__destroy_kernel_maps(session);
207 perf_session__delete_threads(session); 277 perf_session__delete_threads(session);
278 perf_session__release_decomp_events(session);
208 perf_env__exit(&session->header.env); 279 perf_env__exit(&session->header.env);
209 machines__exit(&session->machines); 280 machines__exit(&session->machines);
210 if (session->data) 281 if (session->data)
@@ -439,7 +510,7 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
439 if (tool->feature == NULL) 510 if (tool->feature == NULL)
440 tool->feature = process_event_op2_stub; 511 tool->feature = process_event_op2_stub;
441 if (tool->compressed == NULL) 512 if (tool->compressed == NULL)
442 tool->compressed = perf_session__process_compressed_event_stub; 513 tool->compressed = perf_session__process_compressed_event;
443} 514}
444 515
445static void swap_sample_id_all(union perf_event *event, void *data) 516static void swap_sample_id_all(union perf_event *event, void *data)
@@ -1725,6 +1796,8 @@ static int perf_session__flush_thread_stacks(struct perf_session *session)
1725 1796
1726volatile int session_done; 1797volatile int session_done;
1727 1798
1799static int __perf_session__process_decomp_events(struct perf_session *session);
1800
1728static int __perf_session__process_pipe_events(struct perf_session *session) 1801static int __perf_session__process_pipe_events(struct perf_session *session)
1729{ 1802{
1730 struct ordered_events *oe = &session->ordered_events; 1803 struct ordered_events *oe = &session->ordered_events;
@@ -1805,6 +1878,10 @@ more:
1805 if (skip > 0) 1878 if (skip > 0)
1806 head += skip; 1879 head += skip;
1807 1880
1881 err = __perf_session__process_decomp_events(session);
1882 if (err)
1883 goto out_err;
1884
1808 if (!session_done()) 1885 if (!session_done())
1809 goto more; 1886 goto more;
1810done: 1887done:
@@ -1853,6 +1930,39 @@ fetch_mmaped_event(struct perf_session *session,
1853 return event; 1930 return event;
1854} 1931}
1855 1932
1933static int __perf_session__process_decomp_events(struct perf_session *session)
1934{
1935 s64 skip;
1936 u64 size, file_pos = 0;
1937 struct decomp *decomp = session->decomp_last;
1938
1939 if (!decomp)
1940 return 0;
1941
1942 while (decomp->head < decomp->size && !session_done()) {
1943 union perf_event *event = fetch_mmaped_event(session, decomp->head, decomp->size, decomp->data);
1944
1945 if (!event)
1946 break;
1947
1948 size = event->header.size;
1949
1950 if (size < sizeof(struct perf_event_header) ||
1951 (skip = perf_session__process_event(session, event, file_pos)) < 0) {
1952 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
1953 decomp->file_pos + decomp->head, event->header.size, event->header.type);
1954 return -EINVAL;
1955 }
1956
1957 if (skip)
1958 size += skip;
1959
1960 decomp->head += size;
1961 }
1962
1963 return 0;
1964}
1965
1856/* 1966/*
1857 * On 64bit we can mmap the data file in one go. No need for tiny mmap 1967 * On 64bit we can mmap the data file in one go. No need for tiny mmap
1858 * slices. On 32bit we use 32MB. 1968 * slices. On 32bit we use 32MB.
@@ -1962,6 +2072,10 @@ more:
1962 head += size; 2072 head += size;
1963 file_pos += size; 2073 file_pos += size;
1964 2074
2075 err = __perf_session__process_decomp_events(session);
2076 if (err)
2077 goto out;
2078
1965 ui_progress__update(prog, size); 2079 ui_progress__update(prog, size);
1966 2080
1967 if (session_done()) 2081 if (session_done())