From: Zeev Tarantov <zeev.tarantov@xxxxxxxxx> Zram currently uses LZO compression. With Snappy, it uses less CPU time and is thus more useful. The sacrifice in compression ratio is small. This is an alternate patch that enables choosing between LZO and Snappy only at compile time, as requested by Greg K-H: http://driverdev.linuxdriverproject.org/pipermail/devel/2011-April/015116.html Signed-off-by: Zeev Tarantov <zeev.tarantov@xxxxxxxxx> --- drivers/staging/zram/Kconfig | 20 +++++++++++- drivers/staging/zram/zram_drv.c | 64 ++++++++++++++++++++++++++++++-------- 2 files changed, 68 insertions(+), 16 deletions(-) diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig index 3bec4db..1132f4b 100644 --- a/drivers/staging/zram/Kconfig +++ b/drivers/staging/zram/Kconfig @@ -6,8 +6,6 @@ config ZRAM tristate "Compressed RAM block device support" depends on BLOCK && SYSFS select XVMALLOC - select LZO_COMPRESS - select LZO_DECOMPRESS default n help Creates virtual block devices called /dev/zramX (X = 0, 1, ...). @@ -28,3 +26,21 @@ config ZRAM_DEBUG help This option adds additional debugging code to the compressed RAM block device driver. + +choice ZRAM_COMPRESS + prompt "compression method" + depends on ZRAM + default ZRAM_LZO + help + Select the compression method used by zram. + LZO is the default. Snappy compresses a bit worse (around ~2%) but + much (~2x) faster, at least on x86-64. +config ZRAM_LZO + bool "LZO compression" + select LZO_COMPRESS + select LZO_DECOMPRESS +config ZRAM_SNAPPY + bool "Snappy compression" + depends on SNAPPY_COMPRESS + depends on SNAPPY_DECOMPRESS +endchoice diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index aab4ec4..25ae414 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -29,12 +29,56 @@ #include <linux/genhd.h> #include <linux/highmem.h> #include <linux/slab.h> -#include <linux/lzo.h> #include <linux/string.h> #include <linux/vmalloc.h> #include "zram_drv.h" +#if defined(CONFIG_ZRAM_LZO) +#include <linux/lzo.h> +#define WMSIZE LZO1X_MEM_COMPRESS +#define COMPRESS(s, sl, d, dl, wm) \ + lzo1x_1_compress(s, sl, d, dl, wm) +#define DECOMPRESS(s, sl, d, dl) \ + lzo1x_decompress_safe(s, sl, d, dl) +#elif defined(CONFIG_ZRAM_SNAPPY) +#include "../snappy/csnappy.h" /* if built in drivers/staging */ +#define WMSIZE_ORDER ((PAGE_SHIFT > 14) ? (15) : (PAGE_SHIFT+1)) +#define WMSIZE (1 << WMSIZE_ORDER) +static int +snappy_compress_( + const unsigned char *src, + size_t src_len, + unsigned char *dst, + size_t *dst_len, + void *workmem) +{ + const unsigned char *end = csnappy_compress_fragment( + src, (uint32_t)src_len, dst, workmem, WMSIZE_ORDER); + *dst_len = end - dst; + return 0; +} +static int +snappy_decompress_( + const unsigned char *src, + size_t src_len, + unsigned char *dst, + size_t *dst_len) +{ + uint32_t dst_len_ = (uint32_t)*dst_len; + int ret = csnappy_decompress_noheader(src, src_len, dst, &dst_len_); + *dst_len = (size_t)dst_len_; + return ret; +} +#define COMPRESS(s, sl, d, dl, wm) \ + snappy_compress_(s, sl, d, dl, wm) +#define DECOMPRESS(s, sl, d, dl) \ + snappy_decompress_(s, sl, d, dl) +#else +#error either CONFIG_ZRAM_LZO or CONFIG_ZRAM_SNAPPY must be defined +#endif + + /* Globals */ static int zram_major; struct zram *devices; @@ -251,7 +295,7 @@ static void zram_read(struct zram *zram, struct bio *bio) cmem = kmap_atomic(zram->table[index].page, KM_USER1) + zram->table[index].offset; - ret = lzo1x_decompress_safe( + ret = DECOMPRESS( cmem + sizeof(*zheader), xv_get_object_size(cmem) - sizeof(*zheader), user_mem, &clen); @@ -260,7 +304,7 @@ static void zram_read(struct zram *zram, struct bio *bio) kunmap_atomic(cmem, KM_USER1); /* Should NEVER happen. Return bio error if it does. */ - if (unlikely(ret != LZO_E_OK)) { + if (unlikely(ret)) { pr_err("Decompression failed! err=%d, page=%u\n", ret, index); zram_stat64_inc(zram, &zram->stats.failed_reads); @@ -289,7 +333,6 @@ static void zram_write(struct zram *zram, struct bio *bio) index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; bio_for_each_segment(bvec, bio, i) { - int ret; u32 offset; size_t clen; struct zobj_header *zheader; @@ -319,18 +362,11 @@ static void zram_write(struct zram *zram, struct bio *bio) continue; } - ret = lzo1x_1_compress(user_mem, PAGE_SIZE, src, &clen, - zram->compress_workmem); + COMPRESS(user_mem, PAGE_SIZE, src, &clen, + zram->compress_workmem); kunmap_atomic(user_mem, KM_USER0); - if (unlikely(ret != LZO_E_OK)) { - mutex_unlock(&zram->lock); - pr_err("Compression failed! err=%d\n", ret); - zram_stat64_inc(zram, &zram->stats.failed_writes); - goto out; - } - /* * Page is incompressible. Store it as-is (uncompressed) * since we do not want to return too many disk write @@ -511,7 +547,7 @@ int zram_init_device(struct zram *zram) zram_set_disksize(zram, totalram_pages << PAGE_SHIFT); - zram->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); + zram->compress_workmem = kzalloc(WMSIZE, GFP_KERNEL); if (!zram->compress_workmem) { pr_err("Error allocating compressor working memory!\n"); ret = -ENOMEM; _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel