Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1206831

[RFC][PATCH 3/4] zram: add zlib backend

From Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Newsgroups linux.kernel
Subject [RFC][PATCH 3/4] zram: add zlib backend
Date 2015-08-13 16:00 +0200
Message-ID <pX1d0-56m-25@gated-at.bofh.it> (permalink)
References <pX1cZ-56m-1@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


Add ZLIB backend (disabled yet, will be enalbed in later patch).

======================================================================
TEST

Copy dir with the linux kernel to a zram device (du -sh 2.3G) and check
memory usage stats.

mm_stat fields:
        orig_data_size
        compr_data_size
        mem_used_total
        mem_limit
        mem_used_max
        zero_pages
        num_migrated

zlib
cat /sys/block/zram0/mm_stat
2522685440 1210486447 1230729216        0 1230729216     5461        0

lzo
cat /sys/block/zram0/mm_stat
2525872128 1713351248 1738387456        0 1738387456     4682        0

ZLIB uses 484+MiB less memory in the test.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 drivers/block/zram/Makefile     |   1 +
 drivers/block/zram/zcomp.c      |  11 ++++
 drivers/block/zram/zcomp.h      |   2 +
 drivers/block/zram/zcomp_zlib.c | 120 ++++++++++++++++++++++++++++++++++++++++
 drivers/block/zram/zcomp_zlib.h |  17 ++++++
 5 files changed, 151 insertions(+)
 create mode 100644 drivers/block/zram/zcomp_zlib.c
 create mode 100644 drivers/block/zram/zcomp_zlib.h

diff --git a/drivers/block/zram/Makefile b/drivers/block/zram/Makefile
index be0763f..0922f54 100644
--- a/drivers/block/zram/Makefile
+++ b/drivers/block/zram/Makefile
@@ -1,5 +1,6 @@
 zram-y	:=	zcomp_lzo.o zcomp.o zram_drv.o
 
 zram-$(CONFIG_ZRAM_LZ4_COMPRESS) += zcomp_lz4.o
+zram-$(CONFIG_ZRAM_ZLIB_COMPRESS) += zcomp_zlib.o
 
 obj-$(CONFIG_ZRAM)	+=	zram.o
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index a1c67be..a0cef0b 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -19,6 +19,9 @@
 #ifdef CONFIG_ZRAM_LZ4_COMPRESS
 #include "zcomp_lz4.h"
 #endif
+#ifdef CONFIG_ZRAM_ZLIB_COMPRESS
+#include "zcomp_zlib.h"
+#endif
 
 /*
  * single zcomp_strm backend
@@ -48,6 +51,9 @@ static struct zcomp_backend *backends[] = {
 #ifdef CONFIG_ZRAM_LZ4_COMPRESS
 	&zcomp_lz4,
 #endif
+#ifdef CONFIG_ZRAM_ZLIB_COMPRESS
+	&zcomp_zlib,
+#endif
 	NULL
 };
 
@@ -328,11 +334,16 @@ void zcomp_destroy(struct zcomp *comp)
 
 void *zcomp_decompress_begin(struct zcomp *comp)
 {
+	if (unlikely(comp->backend->flags() & ZCOMP_NEED_READ_ZSTRM))
+		return zcomp_strm_find(comp);
+
 	return NULL;
 }
 
 void zcomp_decompress_end(struct zcomp *comp, void *private)
 {
+	if (unlikely(private))
+		zcomp_strm_release(comp, private);
 }
 
 /*
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
index 5cb9a0b..dbb7f1f 100644
--- a/drivers/block/zram/zcomp.h
+++ b/drivers/block/zram/zcomp.h
@@ -12,6 +12,8 @@
 
 #include <linux/mutex.h>
 
+#define ZCOMP_NEED_READ_ZSTRM	(1 << 0)
+
 struct zcomp_strm {
 	/* compression/decompression buffer */
 	void *buffer;
diff --git a/drivers/block/zram/zcomp_zlib.c b/drivers/block/zram/zcomp_zlib.c
new file mode 100644
index 0000000..711eddd
--- /dev/null
+++ b/drivers/block/zram/zcomp_zlib.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2015 Sergey Senozhatsky.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/zlib.h>
+
+#include "zcomp_zlib.h"
+
+#define ZLIB_COMPRESSION_LEVEL	3
+
+static void *zlib_create(void)
+{
+	z_stream *stream;
+	size_t size;
+
+	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+	if (!stream)
+		return NULL;
+
+	size = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
+			zlib_inflate_workspacesize());
+	stream->workspace = vmalloc(size);
+	if (!stream->workspace) {
+		kfree(stream);
+		stream = NULL;
+	}
+
+	return stream;
+}
+
+static void zlib_destroy(void *private)
+{
+	z_stream *stream = private;
+
+	vfree(stream->workspace);
+	kfree(stream);
+}
+
+static int zlib_flags(void)
+{
+	return ZCOMP_NEED_READ_ZSTRM;
+}
+
+static int zlib_compress(const unsigned char *src, unsigned char *dst,
+		size_t *dst_len, void *private)
+{
+	z_stream *stream = private;
+	int err;
+
+	err = zlib_deflateInit(stream, ZLIB_COMPRESSION_LEVEL);
+	if (err != Z_OK)
+		goto out;
+
+	stream->next_in = src;
+	stream->avail_in = PAGE_SIZE;
+	stream->total_in = 0;
+	stream->next_out = dst;
+	stream->avail_out = PAGE_SIZE;
+	stream->total_out = 0;
+
+	err = zlib_deflate(stream, Z_FINISH);
+	if (err != Z_STREAM_END)
+		goto out;
+
+	err = zlib_deflateEnd(stream);
+	if (err != Z_OK)
+		goto out;
+
+	if (stream->total_out >= stream->total_in)
+		goto out;
+
+	*dst_len = stream->total_out;
+out:
+	return err == Z_OK ? 0 : err;
+}
+
+static int zlib_decompress(const unsigned char *src, size_t src_len,
+		unsigned char *dst, void *private)
+{
+	z_stream *stream = private;
+	int err;
+
+	err = zlib_inflateInit(stream);
+	if (err != Z_OK)
+		goto out;
+
+	stream->next_in = src;
+	stream->avail_in = src_len;
+	stream->total_in = 0;
+	stream->next_out = dst;
+	stream->avail_out = PAGE_SIZE;
+	stream->total_out = 0;
+
+	err = zlib_inflate(stream, Z_FINISH);
+	if (err != Z_STREAM_END)
+		goto out;
+
+	err = zlib_inflateEnd(stream);
+	if (err != Z_OK)
+		goto out;
+out:
+	return err == Z_OK ? 0 : err;
+}
+
+struct zcomp_backend zcomp_zlib = {
+	.compress = zlib_compress,
+	.decompress = zlib_decompress,
+	.create = zlib_create,
+	.destroy = zlib_destroy,
+	.flags = zlib_flags,
+	.name = "zlib",
+};
diff --git a/drivers/block/zram/zcomp_zlib.h b/drivers/block/zram/zcomp_zlib.h
new file mode 100644
index 0000000..d0e4fa0
--- /dev/null
+++ b/drivers/block/zram/zcomp_zlib.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2015 Sergey Senozhatsky.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ZCOMP_ZLIB_H_
+#define _ZCOMP_ZLIB_H_
+
+#include "zcomp.h"
+
+extern struct zcomp_backend zcomp_zlib;
+
+#endif /* _ZCOMP_ZLIB_H_ */
-- 
2.5.0

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

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[RFC][PATCH 0/4] zram: add zlib compression bckend support Sergey Senozhatsky <sergey.senozhatsky@gmail.com> - 2015-08-13 16:00 +0200
  [RFC][PATCH 4/4] zram: enable zlib backend support Sergey Senozhatsky <sergey.senozhatsky@gmail.com> - 2015-08-13 16:00 +0200
  [RFC][PATCH 1/4] zram: introduce zcomp_backend flags callback Sergey Senozhatsky <sergey.senozhatsky@gmail.com> - 2015-08-13 16:00 +0200
  [RFC][PATCH 3/4] zram: add zlib backend Sergey Senozhatsky <sergey.senozhatsky@gmail.com> - 2015-08-13 16:00 +0200
  [RFC][PATCH 2/4] zram: extend zcomp_backend decompress callback Sergey Senozhatsky <sergey.senozhatsky@gmail.com> - 2015-08-13 16:00 +0200

csiph-web