* [RFC PATCH 0/3] add LZ4 compression support @ 2014-01-17 11:04 Sergey Senozhatsky 2014-01-17 11:04 ` [RFC PATCH 1/3] zram: delete zram_init_device() function Sergey Senozhatsky ` (2 more replies) 0 siblings, 3 replies; 11+ messages in thread From: Sergey Senozhatsky @ 2014-01-17 11:04 UTC (permalink / raw) To: Minchan Kim Cc: Jerome Marchand, Nitin Gupta, linux-kernel, Sergey Senozhatsky This patchset introduces support for LZ4 compression (along with LZO) and adds functionality to list and change compression algorithms, using new `compressor' device attribute. Sergey Senozhatsky (3): zram: delete zram_init_device() function zram: introduce zram compressor operations struct zram: list and select compression algorithms Documentation/blockdev/zram.txt | 23 +++++++++--- drivers/block/zram/Kconfig | 2 + drivers/block/zram/zram_drv.c | 83 +++++++++++++++++++++++++++++------------ drivers/block/zram/zram_drv.h | 10 +++++ 4 files changed, 89 insertions(+), 29 deletions(-) -- 1.8.5.3.493.gb139ac2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* [RFC PATCH 1/3] zram: delete zram_init_device() function 2014-01-17 11:04 [RFC PATCH 0/3] add LZ4 compression support Sergey Senozhatsky @ 2014-01-17 11:04 ` Sergey Senozhatsky 2014-01-20 4:43 ` Minchan Kim 2014-01-17 11:04 ` [RFC PATCH 2/3] zram: introduce zram compressor operations struct Sergey Senozhatsky 2014-01-17 11:04 ` [RFC PATCH 3/3] zram: list and select compression algorithms Sergey Senozhatsky 2 siblings, 1 reply; 11+ messages in thread From: Sergey Senozhatsky @ 2014-01-17 11:04 UTC (permalink / raw) To: Minchan Kim Cc: Jerome Marchand, Nitin Gupta, linux-kernel, Sergey Senozhatsky allocate new `zram_meta' in disksize_store() only for uninitialised zram device, saving a number of allocations and deallocations in case if disksize_store() was called on currently used device. at the same time zram_meta stack variable is not necessary, because we can set ->meta directly. there is also no need in setting QUEUE_FLAG_NONROT queue on every disksize_store(), set it once during device creation. Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> --- drivers/block/zram/zram_drv.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 5ec61be..7124042 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -533,38 +533,28 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity) up_write(&zram->init_lock); } -static void zram_init_device(struct zram *zram, struct zram_meta *meta) -{ - /* zram devices sort of resembles non-rotational disks */ - queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue); - zram->meta = meta; - pr_debug("Initialization done!\n"); -} - static ssize_t disksize_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { u64 disksize; - struct zram_meta *meta; struct zram *zram = dev_to_zram(dev); disksize = memparse(buf, NULL); if (!disksize) return -EINVAL; - disksize = PAGE_ALIGN(disksize); - meta = zram_meta_alloc(disksize); down_write(&zram->init_lock); if (init_done(zram)) { up_write(&zram->init_lock); - zram_meta_free(meta); pr_info("Cannot change disksize for initialized device\n"); return -EBUSY; } + disksize = PAGE_ALIGN(disksize); + zram->meta = zram_meta_alloc(disksize); + zram->disksize = disksize; set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); - zram_init_device(zram, meta); up_write(&zram->init_lock); return len; @@ -774,7 +764,8 @@ static int create_device(struct zram *zram, int device_id) /* Actual capacity set using syfs (/sys/block/zram<id>/disksize */ set_capacity(zram->disk, 0); - + /* zram devices sort of resembles non-rotational disks */ + queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue); /* * To ensure that we always get PAGE_SIZE aligned * and n*PAGE_SIZED sized I/O requests. -- 1.8.5.3.493.gb139ac2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 1/3] zram: delete zram_init_device() function 2014-01-17 11:04 ` [RFC PATCH 1/3] zram: delete zram_init_device() function Sergey Senozhatsky @ 2014-01-20 4:43 ` Minchan Kim 0 siblings, 0 replies; 11+ messages in thread From: Minchan Kim @ 2014-01-20 4:43 UTC (permalink / raw) To: Sergey Senozhatsky; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel Hello Sergey, Looks good to me and I found a bug which had been in there so I rebased this patch on the top. https://git.kernel.org/cgit/linux/kernel/git/minchan/linux.git/commit/?h=zram-next&id=241e34fc6c3c1a41575fbe6383436be70df300d1 On Fri, Jan 17, 2014 at 02:04:15PM +0300, Sergey Senozhatsky wrote: > allocate new `zram_meta' in disksize_store() only for uninitialised > zram device, saving a number of allocations and deallocations in case > if disksize_store() was called on currently used device. at the same > time zram_meta stack variable is not necessary, because we can set > ->meta directly. there is also no need in setting QUEUE_FLAG_NONROT > queue on every disksize_store(), set it once during device creation. > > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Otherwise, Acked-by: Minchan Kim <minchan@kernel.org> -- Kind regards, Minchan Kim ^ permalink raw reply [flat|nested] 11+ messages in thread
* [RFC PATCH 2/3] zram: introduce zram compressor operations struct 2014-01-17 11:04 [RFC PATCH 0/3] add LZ4 compression support Sergey Senozhatsky 2014-01-17 11:04 ` [RFC PATCH 1/3] zram: delete zram_init_device() function Sergey Senozhatsky @ 2014-01-17 11:04 ` Sergey Senozhatsky 2014-01-20 5:12 ` Minchan Kim 2014-01-17 11:04 ` [RFC PATCH 3/3] zram: list and select compression algorithms Sergey Senozhatsky 2 siblings, 1 reply; 11+ messages in thread From: Sergey Senozhatsky @ 2014-01-17 11:04 UTC (permalink / raw) To: Minchan Kim Cc: Jerome Marchand, Nitin Gupta, linux-kernel, Sergey Senozhatsky This is preparation patch to add LZ4 compression support. struct zram_compress_ops defines common compress and decompress prototypes. Use these ops->compress and ops->decompress callbacks instead of direct LZO lzo1x_1_compress() and lzo1x_decompress_safe() calls. Compressor ops should be defined before zram meta allocation, because the size of meta->compress_workmem depends on selected compression algorithm. Define LZO compressor ops and set it as the only one available zram compressor at the moment. Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> --- drivers/block/zram/zram_drv.c | 20 +++++++++++++------- drivers/block/zram/zram_drv.h | 10 ++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 7124042..4f2c748 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -28,10 +28,9 @@ #include <linux/device.h> #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 <linux/lzo.h> #include "zram_drv.h" @@ -42,6 +41,12 @@ static struct zram *zram_devices; /* Module params (documentation at end) */ static unsigned int num_devices = 1; +static struct zram_compress_ops lzo_compressor = { + .workmem_sz = LZO1X_MEM_COMPRESS, + .compress = lzo1x_1_compress, + .decompress = lzo1x_decompress_safe, +}; + #define ZRAM_ATTR_RO(name) \ static ssize_t zram_attr_##name##_show(struct device *d, \ struct device_attribute *attr, char *b) \ @@ -166,14 +171,14 @@ static void zram_meta_free(struct zram_meta *meta) kfree(meta); } -static struct zram_meta *zram_meta_alloc(u64 disksize) +static struct zram_meta *zram_meta_alloc(int workmem_sz, u64 disksize) { size_t num_pages; struct zram_meta *meta = kmalloc(sizeof(*meta), GFP_KERNEL); if (!meta) goto out; - meta->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); + meta->compress_workmem = kzalloc(workmem_sz, GFP_KERNEL); if (!meta->compress_workmem) goto free_meta; @@ -301,7 +306,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) if (size == PAGE_SIZE) copy_page(mem, cmem); else - ret = lzo1x_decompress_safe(cmem, size, mem, &clen); + ret = zram->ops->decompress(cmem, size, mem, &clen); zs_unmap_object(meta->mem_pool, handle); read_unlock(&meta->tb_lock); @@ -420,7 +425,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, goto out; } - ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, + ret = zram->ops->compress(uncmem, PAGE_SIZE, src, &clen, meta->compress_workmem); if (!is_partial_io(bvec)) { kunmap_atomic(user_mem); @@ -551,7 +556,7 @@ static ssize_t disksize_store(struct device *dev, } disksize = PAGE_ALIGN(disksize); - zram->meta = zram_meta_alloc(disksize); + zram->meta = zram_meta_alloc(zram->ops->workmem_sz, disksize); zram->disksize = disksize; set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); @@ -785,6 +790,7 @@ static int create_device(struct zram *zram, int device_id) goto out_free_disk; } + zram->ops = &lzo_compressor; zram->meta = NULL; return 0; diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 1d5b1f5..5488682 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -88,8 +88,18 @@ struct zram_meta { struct mutex buffer_lock; /* protect compress buffers */ }; +/* compression/decompression functions and algorithm-specific workmem size */ +struct zram_compress_ops { + int (*compress)(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + int (*decompress)(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len); + long workmem_sz; +}; + struct zram { struct zram_meta *meta; + struct zram_compress_ops *ops; struct request_queue *queue; struct gendisk *disk; /* Prevent concurrent execution of device init, reset and R/W request */ -- 1.8.5.3.493.gb139ac2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 2/3] zram: introduce zram compressor operations struct 2014-01-17 11:04 ` [RFC PATCH 2/3] zram: introduce zram compressor operations struct Sergey Senozhatsky @ 2014-01-20 5:12 ` Minchan Kim 2014-01-20 8:39 ` Sergey Senozhatsky 2014-01-20 10:03 ` Sergey Senozhatsky 0 siblings, 2 replies; 11+ messages in thread From: Minchan Kim @ 2014-01-20 5:12 UTC (permalink / raw) To: Sergey Senozhatsky; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel Hello Sergey, I reviewed this patchset and I suggest somethings. Please have a look and feedback to me. :) 1. Let's define new file zram_comp.c 2. zram_comp includes following field .create .compress .decompress. .destroy .name 1) create/destroy Will set up necessary things like allocating buffer, lock init or other things might happen in future when initialization time. I have a plan to support multiple buffer to do compression/decompression in parallel so we could optimize write VS write path, too. 2) compress/decompress It's very clear. 3) name field will be used for tell to user what's kinds of compression algorithm zram support. On Fri, Jan 17, 2014 at 02:04:16PM +0300, Sergey Senozhatsky wrote: > This is preparation patch to add LZ4 compression support. > > struct zram_compress_ops defines common compress and decompress > prototypes. Use these ops->compress and ops->decompress callbacks > instead of direct LZO lzo1x_1_compress() and lzo1x_decompress_safe() > calls. > > Compressor ops should be defined before zram meta allocation, > because the size of meta->compress_workmem depends on selected > compression algorithm. > > Define LZO compressor ops and set it as the only one available > zram compressor at the moment. > > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> > --- > drivers/block/zram/zram_drv.c | 20 +++++++++++++------- > drivers/block/zram/zram_drv.h | 10 ++++++++++ > 2 files changed, 23 insertions(+), 7 deletions(-) > > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c > index 7124042..4f2c748 100644 > --- a/drivers/block/zram/zram_drv.c > +++ b/drivers/block/zram/zram_drv.c > @@ -28,10 +28,9 @@ > #include <linux/device.h> > #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 <linux/lzo.h> Let's include zram_comps.h only and zram_comps.h includes other compression alrogithms header. If user don't want to support some compression alrogithm, it shouldn't be included. Of course, user can select kinds of compressor in configuration step. > > #include "zram_drv.h" > > @@ -42,6 +41,12 @@ static struct zram *zram_devices; > /* Module params (documentation at end) */ > static unsigned int num_devices = 1; > > +static struct zram_compress_ops lzo_compressor = { > + .workmem_sz = LZO1X_MEM_COMPRESS, workmem_sz should be part of compressor internal. > + .compress = lzo1x_1_compress, > + .decompress = lzo1x_decompress_safe, > +}; > + > #define ZRAM_ATTR_RO(name) \ > static ssize_t zram_attr_##name##_show(struct device *d, \ > struct device_attribute *attr, char *b) \ > @@ -166,14 +171,14 @@ static void zram_meta_free(struct zram_meta *meta) > kfree(meta); > } > > -static struct zram_meta *zram_meta_alloc(u64 disksize) > +static struct zram_meta *zram_meta_alloc(int workmem_sz, u64 disksize) > { > size_t num_pages; > struct zram_meta *meta = kmalloc(sizeof(*meta), GFP_KERNEL); > if (!meta) > goto out; > > - meta->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); > + meta->compress_workmem = kzalloc(workmem_sz, GFP_KERNEL); Instead of exposing compression internal stuff, let's call comp->create. > if (!meta->compress_workmem) > goto free_meta; > > @@ -301,7 +306,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) > if (size == PAGE_SIZE) > copy_page(mem, cmem); > else > - ret = lzo1x_decompress_safe(cmem, size, mem, &clen); > + ret = zram->ops->decompress(cmem, size, mem, &clen); > zs_unmap_object(meta->mem_pool, handle); > read_unlock(&meta->tb_lock); > > @@ -420,7 +425,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, > goto out; > } > > - ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, > + ret = zram->ops->compress(uncmem, PAGE_SIZE, src, &clen, > meta->compress_workmem); Ditto. compress_workmem should be part of compressor itself. > if (!is_partial_io(bvec)) { > kunmap_atomic(user_mem); > @@ -551,7 +556,7 @@ static ssize_t disksize_store(struct device *dev, > } > > disksize = PAGE_ALIGN(disksize); > - zram->meta = zram_meta_alloc(disksize); > + zram->meta = zram_meta_alloc(zram->ops->workmem_sz, disksize); So, we don't need zram->ops->workmem_sz. > > zram->disksize = disksize; > set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); > @@ -785,6 +790,7 @@ static int create_device(struct zram *zram, int device_id) > goto out_free_disk; > } > > + zram->ops = &lzo_compressor; Let's define choose_compressor function with some argument so the result is following as zram->comp = choose_compressor("lzo"); > zram->meta = NULL; > return 0; > > diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h > index 1d5b1f5..5488682 100644 > --- a/drivers/block/zram/zram_drv.h > +++ b/drivers/block/zram/zram_drv.h > @@ -88,8 +88,18 @@ struct zram_meta { > struct mutex buffer_lock; /* protect compress buffers */ > }; > > +/* compression/decompression functions and algorithm-specific workmem size */ > +struct zram_compress_ops { > + int (*compress)(const unsigned char *src, size_t src_len, > + unsigned char *dst, size_t *dst_len, void *wrkmem); > + int (*decompress)(const unsigned char *src, size_t src_len, > + unsigned char *dst, size_t *dst_len); > + long workmem_sz; > +}; > + > struct zram { > struct zram_meta *meta; > + struct zram_compress_ops *ops; > struct request_queue *queue; > struct gendisk *disk; > /* Prevent concurrent execution of device init, reset and R/W request */ > -- > 1.8.5.3.493.gb139ac2 > > -- > 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/ -- Kind regards, Minchan Kim ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 2/3] zram: introduce zram compressor operations struct 2014-01-20 5:12 ` Minchan Kim @ 2014-01-20 8:39 ` Sergey Senozhatsky 2014-01-20 10:03 ` Sergey Senozhatsky 1 sibling, 0 replies; 11+ messages in thread From: Sergey Senozhatsky @ 2014-01-20 8:39 UTC (permalink / raw) To: Minchan Kim; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel On (01/20/14 14:12), Minchan Kim wrote: > Date: Mon, 20 Jan 2014 14:12:33 +0900 > From: Minchan Kim <minchan@kernel.org> > To: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> > Cc: Jerome Marchand <jmarchan@redhat.com>, Nitin Gupta <ngupta@vflare.org>, > linux-kernel@vger.kernel.org > Subject: Re: [RFC PATCH 2/3] zram: introduce zram compressor operations > struct > User-Agent: Mutt/1.5.21 (2010-09-15) > > Hello Sergey, > Hello Minchan, > I reviewed this patchset and I suggest somethings. > Please have a look and feedback to me. :) > > 1. Let's define new file zram_comp.c > 2. zram_comp includes following field > .create > .compress > .decompress. > .destroy > .name > > 1) create/destroy > Will set up necessary things like allocating buffer, lock init or other things > might happen in future when initialization time. > I have a plan to support multiple buffer to do compression/decompression in > parallel so we could optimize write VS write path, too. > I have a patch for this > 2) compress/decompress > > It's very clear. > > 3) name field will be used for tell to user what's kinds of compression > algorithm zram support. > looks good. will start addressing -ss > On Fri, Jan 17, 2014 at 02:04:16PM +0300, Sergey Senozhatsky wrote: > > This is preparation patch to add LZ4 compression support. > > > > struct zram_compress_ops defines common compress and decompress > > prototypes. Use these ops->compress and ops->decompress callbacks > > instead of direct LZO lzo1x_1_compress() and lzo1x_decompress_safe() > > calls. > > > > Compressor ops should be defined before zram meta allocation, > > because the size of meta->compress_workmem depends on selected > > compression algorithm. > > > > Define LZO compressor ops and set it as the only one available > > zram compressor at the moment. > > > > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> > > --- > > drivers/block/zram/zram_drv.c | 20 +++++++++++++------- > > drivers/block/zram/zram_drv.h | 10 ++++++++++ > > 2 files changed, 23 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c > > index 7124042..4f2c748 100644 > > --- a/drivers/block/zram/zram_drv.c > > +++ b/drivers/block/zram/zram_drv.c > > @@ -28,10 +28,9 @@ > > #include <linux/device.h> > > #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 <linux/lzo.h> > > Let's include zram_comps.h only and zram_comps.h includes other compression > alrogithms header. If user don't want to support some compression > alrogithm, it shouldn't be included. > Of course, user can select kinds of compressor in configuration step. > > > > > #include "zram_drv.h" > > > > @@ -42,6 +41,12 @@ static struct zram *zram_devices; > > /* Module params (documentation at end) */ > > static unsigned int num_devices = 1; > > > > +static struct zram_compress_ops lzo_compressor = { > > + .workmem_sz = LZO1X_MEM_COMPRESS, > > workmem_sz should be part of compressor internal. > > > + .compress = lzo1x_1_compress, > > + .decompress = lzo1x_decompress_safe, > > +}; > > + > > #define ZRAM_ATTR_RO(name) \ > > static ssize_t zram_attr_##name##_show(struct device *d, \ > > struct device_attribute *attr, char *b) \ > > @@ -166,14 +171,14 @@ static void zram_meta_free(struct zram_meta *meta) > > kfree(meta); > > } > > > > -static struct zram_meta *zram_meta_alloc(u64 disksize) > > +static struct zram_meta *zram_meta_alloc(int workmem_sz, u64 disksize) > > { > > size_t num_pages; > > struct zram_meta *meta = kmalloc(sizeof(*meta), GFP_KERNEL); > > if (!meta) > > goto out; > > > > - meta->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); > > + meta->compress_workmem = kzalloc(workmem_sz, GFP_KERNEL); > > Instead of exposing compression internal stuff, let's call comp->create. > > > if (!meta->compress_workmem) > > goto free_meta; > > > > @@ -301,7 +306,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) > > if (size == PAGE_SIZE) > > copy_page(mem, cmem); > > else > > - ret = lzo1x_decompress_safe(cmem, size, mem, &clen); > > + ret = zram->ops->decompress(cmem, size, mem, &clen); > > zs_unmap_object(meta->mem_pool, handle); > > read_unlock(&meta->tb_lock); > > > > @@ -420,7 +425,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, > > goto out; > > } > > > > - ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, > > + ret = zram->ops->compress(uncmem, PAGE_SIZE, src, &clen, > > meta->compress_workmem); > > Ditto. compress_workmem should be part of compressor itself. > > > > if (!is_partial_io(bvec)) { > > kunmap_atomic(user_mem); > > @@ -551,7 +556,7 @@ static ssize_t disksize_store(struct device *dev, > > } > > > > disksize = PAGE_ALIGN(disksize); > > - zram->meta = zram_meta_alloc(disksize); > > + zram->meta = zram_meta_alloc(zram->ops->workmem_sz, disksize); > > So, we don't need zram->ops->workmem_sz. > > > > > zram->disksize = disksize; > > set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); > > @@ -785,6 +790,7 @@ static int create_device(struct zram *zram, int device_id) > > goto out_free_disk; > > } > > > > + zram->ops = &lzo_compressor; > > Let's define choose_compressor function with some argument > so the result is following as > > zram->comp = choose_compressor("lzo"); > > > zram->meta = NULL; > > return 0; > > > > diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h > > index 1d5b1f5..5488682 100644 > > --- a/drivers/block/zram/zram_drv.h > > +++ b/drivers/block/zram/zram_drv.h > > @@ -88,8 +88,18 @@ struct zram_meta { > > struct mutex buffer_lock; /* protect compress buffers */ > > }; > > > > +/* compression/decompression functions and algorithm-specific workmem size */ > > +struct zram_compress_ops { > > + int (*compress)(const unsigned char *src, size_t src_len, > > + unsigned char *dst, size_t *dst_len, void *wrkmem); > > + int (*decompress)(const unsigned char *src, size_t src_len, > > + unsigned char *dst, size_t *dst_len); > > + long workmem_sz; > > +}; > > + > > struct zram { > > struct zram_meta *meta; > > + struct zram_compress_ops *ops; > > struct request_queue *queue; > > struct gendisk *disk; > > /* Prevent concurrent execution of device init, reset and R/W request */ > > -- > > 1.8.5.3.493.gb139ac2 > > > > -- > > 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/ > > -- > Kind regards, > Minchan Kim > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 2/3] zram: introduce zram compressor operations struct 2014-01-20 5:12 ` Minchan Kim 2014-01-20 8:39 ` Sergey Senozhatsky @ 2014-01-20 10:03 ` Sergey Senozhatsky 2014-01-21 0:09 ` Minchan Kim 1 sibling, 1 reply; 11+ messages in thread From: Sergey Senozhatsky @ 2014-01-20 10:03 UTC (permalink / raw) To: Minchan Kim; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel On (01/20/14 14:12), Minchan Kim wrote: > Hello Sergey, > > I reviewed this patchset and I suggest somethings. > Please have a look and feedback to me. :) > > 1. Let's define new file zram_comp.c > 2. zram_comp includes following field > .create > .compress > .decompress. > .destroy > .name > alternatively, we can use crypto api, the same way as zswap does (that will require handling of cpu hotplug). -ss > 1) create/destroy > Will set up necessary things like allocating buffer, lock init or other things > might happen in future when initialization time. > I have a plan to support multiple buffer to do compression/decompression in > parallel so we could optimize write VS write path, too. > > 2) compress/decompress > > It's very clear. > > 3) name field will be used for tell to user what's kinds of compression > algorithm zram support. > > On Fri, Jan 17, 2014 at 02:04:16PM +0300, Sergey Senozhatsky wrote: > > This is preparation patch to add LZ4 compression support. > > > > struct zram_compress_ops defines common compress and decompress > > prototypes. Use these ops->compress and ops->decompress callbacks > > instead of direct LZO lzo1x_1_compress() and lzo1x_decompress_safe() > > calls. > > > > Compressor ops should be defined before zram meta allocation, > > because the size of meta->compress_workmem depends on selected > > compression algorithm. > > > > Define LZO compressor ops and set it as the only one available > > zram compressor at the moment. > > > > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> > > --- > > drivers/block/zram/zram_drv.c | 20 +++++++++++++------- > > drivers/block/zram/zram_drv.h | 10 ++++++++++ > > 2 files changed, 23 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c > > index 7124042..4f2c748 100644 > > --- a/drivers/block/zram/zram_drv.c > > +++ b/drivers/block/zram/zram_drv.c > > @@ -28,10 +28,9 @@ > > #include <linux/device.h> > > #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 <linux/lzo.h> > > Let's include zram_comps.h only and zram_comps.h includes other compression > alrogithms header. If user don't want to support some compression > alrogithm, it shouldn't be included. > Of course, user can select kinds of compressor in configuration step. > > > > > #include "zram_drv.h" > > > > @@ -42,6 +41,12 @@ static struct zram *zram_devices; > > /* Module params (documentation at end) */ > > static unsigned int num_devices = 1; > > > > +static struct zram_compress_ops lzo_compressor = { > > + .workmem_sz = LZO1X_MEM_COMPRESS, > > workmem_sz should be part of compressor internal. > > > + .compress = lzo1x_1_compress, > > + .decompress = lzo1x_decompress_safe, > > +}; > > + > > #define ZRAM_ATTR_RO(name) \ > > static ssize_t zram_attr_##name##_show(struct device *d, \ > > struct device_attribute *attr, char *b) \ > > @@ -166,14 +171,14 @@ static void zram_meta_free(struct zram_meta *meta) > > kfree(meta); > > } > > > > -static struct zram_meta *zram_meta_alloc(u64 disksize) > > +static struct zram_meta *zram_meta_alloc(int workmem_sz, u64 disksize) > > { > > size_t num_pages; > > struct zram_meta *meta = kmalloc(sizeof(*meta), GFP_KERNEL); > > if (!meta) > > goto out; > > > > - meta->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); > > + meta->compress_workmem = kzalloc(workmem_sz, GFP_KERNEL); > > Instead of exposing compression internal stuff, let's call comp->create. > > > if (!meta->compress_workmem) > > goto free_meta; > > > > @@ -301,7 +306,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) > > if (size == PAGE_SIZE) > > copy_page(mem, cmem); > > else > > - ret = lzo1x_decompress_safe(cmem, size, mem, &clen); > > + ret = zram->ops->decompress(cmem, size, mem, &clen); > > zs_unmap_object(meta->mem_pool, handle); > > read_unlock(&meta->tb_lock); > > > > @@ -420,7 +425,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, > > goto out; > > } > > > > - ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, > > + ret = zram->ops->compress(uncmem, PAGE_SIZE, src, &clen, > > meta->compress_workmem); > > Ditto. compress_workmem should be part of compressor itself. > > > > if (!is_partial_io(bvec)) { > > kunmap_atomic(user_mem); > > @@ -551,7 +556,7 @@ static ssize_t disksize_store(struct device *dev, > > } > > > > disksize = PAGE_ALIGN(disksize); > > - zram->meta = zram_meta_alloc(disksize); > > + zram->meta = zram_meta_alloc(zram->ops->workmem_sz, disksize); > > So, we don't need zram->ops->workmem_sz. > > > > > zram->disksize = disksize; > > set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); > > @@ -785,6 +790,7 @@ static int create_device(struct zram *zram, int device_id) > > goto out_free_disk; > > } > > > > + zram->ops = &lzo_compressor; > > Let's define choose_compressor function with some argument > so the result is following as > > zram->comp = choose_compressor("lzo"); > > > zram->meta = NULL; > > return 0; > > > > diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h > > index 1d5b1f5..5488682 100644 > > --- a/drivers/block/zram/zram_drv.h > > +++ b/drivers/block/zram/zram_drv.h > > @@ -88,8 +88,18 @@ struct zram_meta { > > struct mutex buffer_lock; /* protect compress buffers */ > > }; > > > > +/* compression/decompression functions and algorithm-specific workmem size */ > > +struct zram_compress_ops { > > + int (*compress)(const unsigned char *src, size_t src_len, > > + unsigned char *dst, size_t *dst_len, void *wrkmem); > > + int (*decompress)(const unsigned char *src, size_t src_len, > > + unsigned char *dst, size_t *dst_len); > > + long workmem_sz; > > +}; > > + > > struct zram { > > struct zram_meta *meta; > > + struct zram_compress_ops *ops; > > struct request_queue *queue; > > struct gendisk *disk; > > /* Prevent concurrent execution of device init, reset and R/W request */ > > -- > > 1.8.5.3.493.gb139ac2 > > > > -- > > 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/ > > -- > Kind regards, > Minchan Kim > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 2/3] zram: introduce zram compressor operations struct 2014-01-20 10:03 ` Sergey Senozhatsky @ 2014-01-21 0:09 ` Minchan Kim 2014-01-21 8:47 ` Sergey Senozhatsky 0 siblings, 1 reply; 11+ messages in thread From: Minchan Kim @ 2014-01-21 0:09 UTC (permalink / raw) To: Sergey Senozhatsky; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel On Mon, Jan 20, 2014 at 01:03:48PM +0300, Sergey Senozhatsky wrote: > On (01/20/14 14:12), Minchan Kim wrote: > > Hello Sergey, > > > > I reviewed this patchset and I suggest somethings. > > Please have a look and feedback to me. :) > > > > 1. Let's define new file zram_comp.c > > 2. zram_comp includes following field > > .create > > .compress > > .decompress. > > .destroy > > .name > > > > alternatively, we can use crypto api, the same way as zswap does (that > will require handling of cpu hotplug). > > -ss I really doubt what's the benefit from crypto API for zram. It's maybe since I'm not familiar with it so I should ask a silly question. 1. What's the runtime overhead for using such frontend? As you know, zram is in-memory block device so I don't want to add unnecessary overhead to optimize. 2. What's the memory footprint for using such frontend? As you know, zram is very popular for small-memory embedded device so I don't want to consume more runtime memory and static memory due to CONFIG_CRYPTO friend. 3. Is it a flexible to alloc/handle multiple compressor buffer for the our purpose? zswap and zcache have been used it with per-cpu buffer but it would a problem for write scalabitliy if we uses zlib which takes long time to compress. When I read code, maybe we can allocate multiple buffers through cryptop_alloc_compo several time but it would cause 1) and 2) problem again. So, what's the attractive point for using crypto? One of thing I could imagine is that it could make zram H/W compressor but I don't have heard about it so if we don't have any special reason, I'd like to go with raw compressor so we can get a *base* number. Then, if we really need crypto API, we can change it easily and benchmark. Finally, we could get a comparision number in future and it would make the decision easily. Thanks. -- Kind regards, Minchan Kim ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 2/3] zram: introduce zram compressor operations struct 2014-01-21 0:09 ` Minchan Kim @ 2014-01-21 8:47 ` Sergey Senozhatsky 0 siblings, 0 replies; 11+ messages in thread From: Sergey Senozhatsky @ 2014-01-21 8:47 UTC (permalink / raw) To: Minchan Kim; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel On (01/21/14 09:09), Minchan Kim wrote: > On Mon, Jan 20, 2014 at 01:03:48PM +0300, Sergey Senozhatsky wrote: > > On (01/20/14 14:12), Minchan Kim wrote: > > > Hello Sergey, > > > > > > I reviewed this patchset and I suggest somethings. > > > Please have a look and feedback to me. :) > > > > > > 1. Let's define new file zram_comp.c > > > 2. zram_comp includes following field > > > .create > > > .compress > > > .decompress. > > > .destroy > > > .name > > > > > > > alternatively, we can use crypto api, the same way as zswap does (that > > will require handling of cpu hotplug). > > > > -ss > > I really doubt what's the benefit from crypto API for zram. > It's maybe since I'm not familiar with it so I should ask a silly > question. > > 1. What's the runtime overhead for using such frontend? > > As you know, zram is in-memory block device so I don't want to > add unnecessary overhead to optimize. > > 2. What's the memory footprint for using such frontend? > > As you know, zram is very popular for small-memory embedded device > so I don't want to consume more runtime memory and static memory > due to CONFIG_CRYPTO friend. > schematically: char *compressor = "lzo"; /* or supplied by user via COMPRESSOR_store() */ if (crypto_has_comp(compressor, 0, 0)) { tfms = alloc_percpu(struct crypto_comp *); tfm = crypto_alloc_comp(compressor, 0, 0); *per_cpu_ptr(tfms, cpu) = tfm; } ret = crypto_comp_compress(tfm, src, slen, dst, dlen); and ret = crypto_comp_decompress(tfm, src, slen, dst, dlen); memory overhead looks like a bunch of structures (transformation contexts -- tfm). they touch tfm within compress/decompress, so crypto users usually allocate per cpu tfm or somehow protect parallel tfm usage, which is a big disadvantage to my opinion. otoh, crypto provides HC compressors (LZ4HC at the moment). my choice is to use raw compressor (as I did in initial patchset). -ss > 3. Is it a flexible to alloc/handle multiple compressor buffer for > the our purpose? zswap and zcache have been used it with per-cpu > buffer but it would a problem for write scalabitliy if we uses zlib > which takes long time to compress. > When I read code, maybe we can allocate multiple buffers through > cryptop_alloc_compo several time but it would cause 1) and 2) problem > again. > > So, what's the attractive point for using crypto? > One of thing I could imagine is that it could make zram H/W compressor > but I don't have heard about it so if we don't have any special reason, > I'd like to go with raw compressor so we can get a *base* number. Then, > if we really need crypto API, we can change it easily and benchmark. > Finally, we could get a comparision number in future and it would make > the decision easily. > > Thanks. > > -- > Kind regards, > Minchan Kim > ^ permalink raw reply [flat|nested] 11+ messages in thread
* [RFC PATCH 3/3] zram: list and select compression algorithms 2014-01-17 11:04 [RFC PATCH 0/3] add LZ4 compression support Sergey Senozhatsky 2014-01-17 11:04 ` [RFC PATCH 1/3] zram: delete zram_init_device() function Sergey Senozhatsky 2014-01-17 11:04 ` [RFC PATCH 2/3] zram: introduce zram compressor operations struct Sergey Senozhatsky @ 2014-01-17 11:04 ` Sergey Senozhatsky 2014-01-20 5:18 ` Minchan Kim 2 siblings, 1 reply; 11+ messages in thread From: Sergey Senozhatsky @ 2014-01-17 11:04 UTC (permalink / raw) To: Minchan Kim Cc: Jerome Marchand, Nitin Gupta, linux-kernel, Sergey Senozhatsky Add compressor device attr that allows to list and select compression algorithms. Define and make available for selection LZ4 compressor ops. usage example: List available compression algorithms (currently selected one is LZO): cat /sys/block/zram0/compressor <lzo> lz4 Change compression algorithm to LZ4: echo lz4 > /sys/block/zram0/compressor cat /sys/block/zram0/compressor lzo <lz4> Update documentation with "Select compression algorithm" section Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> --- Documentation/blockdev/zram.txt | 23 ++++++++++++++++----- drivers/block/zram/Kconfig | 2 ++ drivers/block/zram/zram_drv.c | 46 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt index 393541be..af90d29 100644 --- a/Documentation/blockdev/zram.txt +++ b/Documentation/blockdev/zram.txt @@ -21,7 +21,20 @@ Following shows a typical sequence of steps for using zram. This creates 4 devices: /dev/zram{0,1,2,3} (num_devices parameter is optional. Default: 1) -2) Set Disksize +2) Select compression algorithm +'compressor' sysfs node allows to see available, currently used +and change compression algorithms. +In order to list available compression algorithms (currently selected +one is LZO): + cat /sys/block/zram0/compressor + <lzo> lz4 + +Change compression algorithm to LZ4: + echo lz4 > /sys/block/zram0/compressor + cat /sys/block/zram0/compressor + lzo <lz4> + +3) Set Disksize Set disk size by writing the value to sysfs node 'disksize'. The value can be either in bytes or you can use mem suffixes. Examples: @@ -38,14 +51,14 @@ There is little point creating a zram of greater than twice the size of memory since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the size of the disk when not in use so a huge zram is wasteful. -3) Activate: +4) Activate: mkswap /dev/zram0 swapon /dev/zram0 mkfs.ext4 /dev/zram1 mount /dev/zram1 /tmp -4) Stats: +5) Stats: Per-device statistics are exported as various nodes under /sys/block/zram<id>/ disksize @@ -59,11 +72,11 @@ size of the disk when not in use so a huge zram is wasteful. compr_data_size mem_used_total -5) Deactivate: +6) Deactivate: swapoff /dev/zram0 umount /dev/zram1 -6) Reset: +7) Reset: Write any positive value to 'reset' sysfs node echo 1 > /sys/block/zram0/reset echo 1 > /sys/block/zram1/reset diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig index 3450be8..09dacd6 100644 --- a/drivers/block/zram/Kconfig +++ b/drivers/block/zram/Kconfig @@ -3,6 +3,8 @@ config ZRAM depends on BLOCK && SYSFS && ZSMALLOC select LZO_COMPRESS select LZO_DECOMPRESS + select LZ4_COMPRESS + select LZ4_DECOMPRESS default n help Creates virtual block devices called /dev/zramX (X = 0, 1, ...). diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 4f2c748..f1434f8 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -31,6 +31,7 @@ #include <linux/string.h> #include <linux/vmalloc.h> #include <linux/lzo.h> +#include <linux/lz4.h> #include "zram_drv.h" @@ -47,6 +48,12 @@ static struct zram_compress_ops lzo_compressor = { .decompress = lzo1x_decompress_safe, }; +static struct zram_compress_ops lz4_compressor = { + .workmem_sz = LZ4_MEM_COMPRESS, + .compress = lz4_compress, + .decompress = lz4_decompress_unknownoutputsize, +}; + #define ZRAM_ATTR_RO(name) \ static ssize_t zram_attr_##name##_show(struct device *d, \ struct device_attribute *attr, char *b) \ @@ -113,6 +120,34 @@ static ssize_t mem_used_total_show(struct device *dev, return sprintf(buf, "%llu\n", val); } +static ssize_t compressor_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct zram *zram = dev_to_zram(dev); + if (zram->ops == &lzo_compressor) + return sprintf(buf, "<lzo> lz4\n"); + return sprintf(buf, "lzo <lz4>\n"); +} + +static ssize_t compressor_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct zram *zram = dev_to_zram(dev); + + down_write(&zram->init_lock); + if (init_done(zram)) { + up_write(&zram->init_lock); + pr_info("Cannot change compressor for initialized device\n"); + return -EBUSY; + } + if (strncmp(buf, "lzo", 3) == 0) + zram->ops = &lzo_compressor; + else + zram->ops = &lz4_compressor; + up_write(&zram->init_lock); + return len; +} + /* flag operations needs meta->tb_lock */ static int zram_test_flag(struct zram_meta *meta, u32 index, enum zram_pageflags flag) @@ -285,7 +320,7 @@ static void zram_free_page(struct zram *zram, size_t index) static int zram_decompress_page(struct zram *zram, char *mem, u32 index) { - int ret = LZO_E_OK; + int ret = 0; size_t clen = PAGE_SIZE; unsigned char *cmem; struct zram_meta *meta = zram->meta; @@ -311,7 +346,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) read_unlock(&meta->tb_lock); /* 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); atomic64_inc(&zram->stats.failed_reads); return ret; @@ -354,7 +389,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, ret = zram_decompress_page(zram, uncmem, index); /* Should NEVER happen. Return bio error if it does. */ - if (unlikely(ret != LZO_E_OK)) + if (unlikely(ret)) goto out_cleanup; if (is_partial_io(bvec)) @@ -433,7 +468,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, uncmem = NULL; } - if (unlikely(ret != LZO_E_OK)) { + if (unlikely(ret)) { pr_err("Compression failed! err=%d\n", ret); goto out; } @@ -705,6 +740,8 @@ static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL); static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store); static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL); static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); +static DEVICE_ATTR(compressor, S_IRUGO | S_IWUSR, + compressor_show, compressor_store); ZRAM_ATTR_RO(num_reads); ZRAM_ATTR_RO(num_writes); @@ -719,6 +756,7 @@ static struct attribute *zram_disk_attrs[] = { &dev_attr_disksize.attr, &dev_attr_initstate.attr, &dev_attr_reset.attr, + &dev_attr_compressor.attr, &dev_attr_num_reads.attr, &dev_attr_num_writes.attr, &dev_attr_failed_reads.attr, -- 1.8.5.3.493.gb139ac2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 3/3] zram: list and select compression algorithms 2014-01-17 11:04 ` [RFC PATCH 3/3] zram: list and select compression algorithms Sergey Senozhatsky @ 2014-01-20 5:18 ` Minchan Kim 0 siblings, 0 replies; 11+ messages in thread From: Minchan Kim @ 2014-01-20 5:18 UTC (permalink / raw) To: Sergey Senozhatsky; +Cc: Jerome Marchand, Nitin Gupta, linux-kernel On Fri, Jan 17, 2014 at 02:04:17PM +0300, Sergey Senozhatsky wrote: > Add compressor device attr that allows to list and select > compression algorithms. > > Define and make available for selection LZ4 compressor ops. > > usage example: > List available compression algorithms (currently selected > one is LZO): > cat /sys/block/zram0/compressor > <lzo> lz4 > > Change compression algorithm to LZ4: > echo lz4 > /sys/block/zram0/compressor > cat /sys/block/zram0/compressor > lzo <lz4> Interface looks good to me. > > Update documentation with "Select compression algorithm" section > > Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> > --- > Documentation/blockdev/zram.txt | 23 ++++++++++++++++----- > drivers/block/zram/Kconfig | 2 ++ > drivers/block/zram/zram_drv.c | 46 +++++++++++++++++++++++++++++++++++++---- > 3 files changed, 62 insertions(+), 9 deletions(-) > > diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt > index 393541be..af90d29 100644 > --- a/Documentation/blockdev/zram.txt > +++ b/Documentation/blockdev/zram.txt > @@ -21,7 +21,20 @@ Following shows a typical sequence of steps for using zram. > This creates 4 devices: /dev/zram{0,1,2,3} > (num_devices parameter is optional. Default: 1) > > -2) Set Disksize > +2) Select compression algorithm > +'compressor' sysfs node allows to see available, currently used > +and change compression algorithms. > +In order to list available compression algorithms (currently selected > +one is LZO): > + cat /sys/block/zram0/compressor > + <lzo> lz4 > + > +Change compression algorithm to LZ4: > + echo lz4 > /sys/block/zram0/compressor > + cat /sys/block/zram0/compressor > + lzo <lz4> > + > +3) Set Disksize > Set disk size by writing the value to sysfs node 'disksize'. > The value can be either in bytes or you can use mem suffixes. > Examples: > @@ -38,14 +51,14 @@ There is little point creating a zram of greater than twice the size of memory > since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the > size of the disk when not in use so a huge zram is wasteful. > > -3) Activate: > +4) Activate: > mkswap /dev/zram0 > swapon /dev/zram0 > > mkfs.ext4 /dev/zram1 > mount /dev/zram1 /tmp > > -4) Stats: > +5) Stats: > Per-device statistics are exported as various nodes under > /sys/block/zram<id>/ > disksize > @@ -59,11 +72,11 @@ size of the disk when not in use so a huge zram is wasteful. > compr_data_size > mem_used_total > > -5) Deactivate: > +6) Deactivate: > swapoff /dev/zram0 > umount /dev/zram1 > > -6) Reset: > +7) Reset: > Write any positive value to 'reset' sysfs node > echo 1 > /sys/block/zram0/reset > echo 1 > /sys/block/zram1/reset > diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig > index 3450be8..09dacd6 100644 > --- a/drivers/block/zram/Kconfig > +++ b/drivers/block/zram/Kconfig > @@ -3,6 +3,8 @@ config ZRAM > depends on BLOCK && SYSFS && ZSMALLOC > select LZO_COMPRESS > select LZO_DECOMPRESS > + select LZ4_COMPRESS > + select LZ4_DECOMPRESS But user should select what kinds of compressor then want some user want only lzo while others want lzo, lz2 and zlib all. > default n > help > Creates virtual block devices called /dev/zramX (X = 0, 1, ...). > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c > index 4f2c748..f1434f8 100644 > --- a/drivers/block/zram/zram_drv.c > +++ b/drivers/block/zram/zram_drv.c > @@ -31,6 +31,7 @@ > #include <linux/string.h> > #include <linux/vmalloc.h> > #include <linux/lzo.h> > +#include <linux/lz4.h> > > #include "zram_drv.h" > > @@ -47,6 +48,12 @@ static struct zram_compress_ops lzo_compressor = { > .decompress = lzo1x_decompress_safe, > }; > > +static struct zram_compress_ops lz4_compressor = { > + .workmem_sz = LZ4_MEM_COMPRESS, > + .compress = lz4_compress, > + .decompress = lz4_decompress_unknownoutputsize, > +}; > + > #define ZRAM_ATTR_RO(name) \ > static ssize_t zram_attr_##name##_show(struct device *d, \ > struct device_attribute *attr, char *b) \ > @@ -113,6 +120,34 @@ static ssize_t mem_used_total_show(struct device *dev, > return sprintf(buf, "%llu\n", val); > } > > +static ssize_t compressor_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct zram *zram = dev_to_zram(dev); > + if (zram->ops == &lzo_compressor) > + return sprintf(buf, "<lzo> lz4\n"); > + return sprintf(buf, "lzo <lz4>\n"); > +} > + > +static ssize_t compressor_store(struct device *dev, > + struct device_attribute *attr, const char *buf, size_t len) > +{ > + struct zram *zram = dev_to_zram(dev); > + > + down_write(&zram->init_lock); > + if (init_done(zram)) { > + up_write(&zram->init_lock); > + pr_info("Cannot change compressor for initialized device\n"); > + return -EBUSY; > + } > + if (strncmp(buf, "lzo", 3) == 0) > + zram->ops = &lzo_compressor; > + else > + zram->ops = &lz4_compressor; > + up_write(&zram->init_lock); > + return len; > +} Changing compressow should be allowed only when zram was created or reset. IOW, there should be no datacompressed by old compressor in memory. > + > /* flag operations needs meta->tb_lock */ > static int zram_test_flag(struct zram_meta *meta, u32 index, > enum zram_pageflags flag) > @@ -285,7 +320,7 @@ static void zram_free_page(struct zram *zram, size_t index) > > static int zram_decompress_page(struct zram *zram, char *mem, u32 index) > { > - int ret = LZO_E_OK; > + int ret = 0; > size_t clen = PAGE_SIZE; > unsigned char *cmem; > struct zram_meta *meta = zram->meta; > @@ -311,7 +346,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) > read_unlock(&meta->tb_lock); > > /* 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); > atomic64_inc(&zram->stats.failed_reads); > return ret; > @@ -354,7 +389,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, > > ret = zram_decompress_page(zram, uncmem, index); > /* Should NEVER happen. Return bio error if it does. */ > - if (unlikely(ret != LZO_E_OK)) > + if (unlikely(ret)) > goto out_cleanup; > > if (is_partial_io(bvec)) > @@ -433,7 +468,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, > uncmem = NULL; > } > > - if (unlikely(ret != LZO_E_OK)) { > + if (unlikely(ret)) { > pr_err("Compression failed! err=%d\n", ret); > goto out; > } > @@ -705,6 +740,8 @@ static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL); > static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store); > static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL); > static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); > +static DEVICE_ATTR(compressor, S_IRUGO | S_IWUSR, > + compressor_show, compressor_store); > > ZRAM_ATTR_RO(num_reads); > ZRAM_ATTR_RO(num_writes); > @@ -719,6 +756,7 @@ static struct attribute *zram_disk_attrs[] = { > &dev_attr_disksize.attr, > &dev_attr_initstate.attr, > &dev_attr_reset.attr, > + &dev_attr_compressor.attr, > &dev_attr_num_reads.attr, > &dev_attr_num_writes.attr, > &dev_attr_failed_reads.attr, > -- > 1.8.5.3.493.gb139ac2 > > -- > 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/ -- Kind regards, Minchan Kim ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2014-01-21 8:50 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-01-17 11:04 [RFC PATCH 0/3] add LZ4 compression support Sergey Senozhatsky 2014-01-17 11:04 ` [RFC PATCH 1/3] zram: delete zram_init_device() function Sergey Senozhatsky 2014-01-20 4:43 ` Minchan Kim 2014-01-17 11:04 ` [RFC PATCH 2/3] zram: introduce zram compressor operations struct Sergey Senozhatsky 2014-01-20 5:12 ` Minchan Kim 2014-01-20 8:39 ` Sergey Senozhatsky 2014-01-20 10:03 ` Sergey Senozhatsky 2014-01-21 0:09 ` Minchan Kim 2014-01-21 8:47 ` Sergey Senozhatsky 2014-01-17 11:04 ` [RFC PATCH 3/3] zram: list and select compression algorithms Sergey Senozhatsky 2014-01-20 5:18 ` Minchan Kim
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.