All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexey Budankov <alexey.budankov@linux.intel.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>, Namhyung Kim <namhyung@kernel.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Ingo Molnar <mingo@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Andi Kleen <ak@linux.intel.com>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: [PATCH v9 06/12] perf util: introduce Zstd streaming based compression API
Date: Sat, 16 Mar 2019 17:13:50 +0300	[thread overview]
Message-ID: <4e4433a6-250e-651a-bb1c-243e3cbbf4af@linux.intel.com> (raw)
In-Reply-To: <c1423198-e474-1739-e800-4615cce501ce@linux.intel.com>


Implemented functions are based on Zstd streaming compression API.
The functions are used in runtime to compress data that come from
mmaped kernel buffer. zstd_init(), zstd_fini() are used for
initialization and finalization to allocate and deallocate internal
zstd objects. zstd_compress_stream_to_records() is used to convert
parts of mmaped kernel buffer into an array of PERF_RECORD_COMPRESSED
records.

Signed-off-by: Alexey Budankov <alexey.budankov@linux.intel.com>
---
 tools/perf/util/Build      |  2 ++
 tools/perf/util/compress.h | 43 +++++++++++++++++++++++
 tools/perf/util/zstd.c     | 71 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 tools/perf/util/zstd.c

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 8dd3102301ea..6d5bbc8b589b 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -145,6 +145,8 @@ perf-y += scripting-engines/
 
 perf-$(CONFIG_ZLIB) += zlib.o
 perf-$(CONFIG_LZMA) += lzma.o
+perf-$(CONFIG_ZSTD) += zstd.o
+
 perf-y += demangle-java.o
 perf-y += demangle-rust.o
 
diff --git a/tools/perf/util/compress.h b/tools/perf/util/compress.h
index 892e92e7e7fc..d00d7cb095aa 100644
--- a/tools/perf/util/compress.h
+++ b/tools/perf/util/compress.h
@@ -2,6 +2,11 @@
 #ifndef PERF_COMPRESS_H
 #define PERF_COMPRESS_H
 
+#include <stdbool.h>
+#ifdef HAVE_ZSTD_SUPPORT
+#include <zstd.h>
+#endif
+
 #ifdef HAVE_ZLIB_SUPPORT
 int gzip_decompress_to_file(const char *input, int output_fd);
 bool gzip_is_compressed(const char *input);
@@ -12,4 +17,42 @@ int lzma_decompress_to_file(const char *input, int output_fd);
 bool lzma_is_compressed(const char *input);
 #endif
 
+struct zstd_data {
+#ifdef HAVE_ZSTD_SUPPORT
+	ZSTD_CStream	*cstream;
+#endif
+};
+
+#ifdef HAVE_ZSTD_SUPPORT
+
+int zstd_init(struct zstd_data *data, int level);
+int zstd_fini(struct zstd_data *data);
+
+size_t zstd_compress_stream_to_records(struct zstd_data *data,
+	void *dst, size_t dst_size, void *src, size_t src_size,	size_t max_record_size,
+	size_t process_header(void *record, size_t increment));
+
+#else /* !HAVE_ZSTD_SUPPORT */
+
+static inline int zstd_init(struct zstd_data *data __maybe_unused, int level __maybe_unused)
+{
+	return 0;
+}
+
+static inline int zstd_fini(struct zstd_data *data __maybe_unused)
+{
+	return 0;
+}
+
+static inline size_t zstd_compress_stream_to_records(struct zstd_data *data __maybe_unused,
+		void *dst __maybe_unused, size_t dst_size __maybe_unused,
+		void *src __maybe_unused, size_t src_size __maybe_unused,
+		size_t max_record_size __maybe_unused,
+		size_t process_header(void *record, size_t increment) __maybe_unused)
+{
+	return 0;
+}
+
+#endif
+
 #endif /* PERF_COMPRESS_H */
diff --git a/tools/perf/util/zstd.c b/tools/perf/util/zstd.c
new file mode 100644
index 000000000000..6d4f69d57567
--- /dev/null
+++ b/tools/perf/util/zstd.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <string.h>
+
+#include "util/compress.h"
+#include "util/debug.h"
+
+int zstd_init(struct zstd_data *data, int level)
+{
+	size_t ret;
+
+	data->cstream = ZSTD_createCStream();
+	if (data->cstream == NULL) {
+		pr_err("Couldn't create compression stream.\n");
+		return -1;
+	}
+
+	ret = ZSTD_initCStream(data->cstream, level);
+	if (ZSTD_isError(ret)) {
+		pr_err("Failed to initialize compression stream: %s\n", ZSTD_getErrorName(ret));
+		return -1;
+	}
+
+	return 0;
+}
+
+int zstd_fini(struct zstd_data *data)
+{
+	if (data->cstream) {
+		ZSTD_freeCStream(data->cstream);
+		data->cstream = NULL;
+	}
+
+	return 0;
+}
+
+size_t zstd_compress_stream_to_records(struct zstd_data *data,
+	void *dst, size_t dst_size, void *src, size_t src_size,	size_t max_record_size,
+	size_t process_header(void *record, size_t increment))
+{
+	size_t ret, size, compressed = 0;
+	ZSTD_inBuffer input = { src, src_size, 0 };
+	ZSTD_outBuffer output;
+	void *record;
+
+	while (input.pos < input.size) {
+		record = dst;
+		size = process_header(record, 0);
+		compressed += size;
+		dst += size;
+		dst_size -= size;
+		output = (ZSTD_outBuffer){ dst, (dst_size > max_record_size) ?
+						max_record_size : dst_size, 0 };
+		ret = ZSTD_compressStream(data->cstream, &output, &input);
+		ZSTD_flushStream(data->cstream, &output);
+		if (ZSTD_isError(ret)) {
+			pr_err("failed to compress %ld bytes: %s\n",
+				(long)src_size, ZSTD_getErrorName(ret));
+			memcpy(dst, src, src_size);
+			return src_size;
+		}
+		size = output.pos;
+		size = process_header(record, size);
+		compressed += size;
+		dst += size;
+		dst_size -= size;
+	}
+
+	return compressed;
+}
+
-- 
2.20.1


  parent reply	other threads:[~2019-03-16 14:13 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-16  8:58 [PATCH v9 00/12] perf: enable compression of record mode trace to save storage space Alexey Budankov
2019-03-16 14:09 ` [PATCH v9 01/12] feature: implement libzstd check, LIBZSTD_DIR and NO_LIBZSTD defines Alexey Budankov
2019-03-16 14:10 ` [PATCH v9 02/12] perf record: implement --mmap-flush=<number> option Alexey Budankov
2019-03-16 14:11 ` [PATCH v9 03/12] perf session: define bytes_transferred and bytes_compressed metrics Alexey Budankov
2019-03-16 14:12 ` [PATCH v9 04/12] perf record: implement COMPRESSED event record and its attributes Alexey Budankov
2019-03-16 14:13 ` [PATCH v9 05/12] perf mmap: implement dedicated memory buffer for data compression Alexey Budankov
2019-03-16 14:13 ` Alexey Budankov [this message]
2019-03-16 14:14 ` [PATCH v9 07/12] perf record: implement compression for serial trace streaming Alexey Budankov
2019-03-16 14:15 ` [PATCH v9 08/12] perf record: implement compression for AIO " Alexey Budankov
2019-03-16 14:16 ` [PATCH v9 09/12] perf record: implement -z,--compression_level[=<n>] option Alexey Budankov
2019-03-16 14:17 ` [PATCH v9 10/12] perf report: implement record trace decompression Alexey Budankov
2019-03-18 11:46   ` Jiri Olsa
2019-03-18 12:06     ` Alexey Budankov
2019-03-16 14:17 ` [PATCH v9 11/12] perf inject: enable COMPRESSED records decompression Alexey Budankov
2019-03-16 14:18 ` [PATCH v9 12/12] perf tests: implement Zstd comp/decomp integration test Alexey Budankov
2019-03-18 11:46   ` Jiri Olsa
2019-03-18 12:07     ` Alexey Budankov
2019-03-18 11:46 ` [PATCH v9 00/12] perf: enable compression of record mode trace to save storage space Jiri Olsa
2019-03-18 17:57   ` Alexey Budankov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4e4433a6-250e-651a-bb1c-243e3cbbf4af@linux.intel.com \
    --to=alexey.budankov@linux.intel.com \
    --cc=acme@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.