diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-block-zram | 8 | ||||
| -rw-r--r-- | Documentation/blockdev/zram.txt | 24 | ||||
| -rw-r--r-- | drivers/block/zram/zcomp.c | 32 | ||||
| -rw-r--r-- | drivers/block/zram/zcomp.h | 2 | ||||
| -rw-r--r-- | drivers/block/zram/zram_drv.c | 37 | ||||
| -rw-r--r-- | drivers/block/zram/zram_drv.h | 1 |
6 files changed, 93 insertions, 11 deletions
diff --git a/Documentation/ABI/testing/sysfs-block-zram b/Documentation/ABI/testing/sysfs-block-zram index 0da9ed6b82ea..70ec992514d0 100644 --- a/Documentation/ABI/testing/sysfs-block-zram +++ b/Documentation/ABI/testing/sysfs-block-zram | |||
| @@ -65,6 +65,14 @@ Description: | |||
| 65 | number of backend's zcomp_strm compression streams (number of | 65 | number of backend's zcomp_strm compression streams (number of |
| 66 | concurrent compress operations). | 66 | concurrent compress operations). |
| 67 | 67 | ||
| 68 | What: /sys/block/zram<id>/comp_algorithm | ||
| 69 | Date: February 2014 | ||
| 70 | Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> | ||
| 71 | Description: | ||
| 72 | The comp_algorithm file is read-write and lets to show | ||
| 73 | available and selected compression algorithms, change | ||
| 74 | compression algorithm selection. | ||
| 75 | |||
| 68 | What: /sys/block/zram<id>/notify_free | 76 | What: /sys/block/zram<id>/notify_free |
| 69 | Date: August 2010 | 77 | Date: August 2010 |
| 70 | Contact: Nitin Gupta <ngupta@vflare.org> | 78 | Contact: Nitin Gupta <ngupta@vflare.org> |
diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt index aadfe60391b7..2604ffed51db 100644 --- a/Documentation/blockdev/zram.txt +++ b/Documentation/blockdev/zram.txt | |||
| @@ -42,7 +42,21 @@ will not take any effect, because single stream compression backend implemented | |||
| 42 | as a special case and does not support dynamic max_comp_streams. Only multi | 42 | as a special case and does not support dynamic max_comp_streams. Only multi |
| 43 | stream backend supports dynamic max_comp_streams adjustment. | 43 | stream backend supports dynamic max_comp_streams adjustment. |
| 44 | 44 | ||
| 45 | 3) Set Disksize | 45 | 3) Select compression algorithm |
| 46 | Using comp_algorithm device attribute one can see available and | ||
| 47 | currently selected (shown in square brackets) compression algortithms, | ||
| 48 | change selected compression algorithm (once the device is initialised | ||
| 49 | there is no way to change compression algorithm). | ||
| 50 | |||
| 51 | Examples: | ||
| 52 | #show supported compression algorithms | ||
| 53 | cat /sys/block/zram0/comp_algorithm | ||
| 54 | lzo [lz4] | ||
| 55 | |||
| 56 | #select lzo compression algorithm | ||
| 57 | echo lzo > /sys/block/zram0/comp_algorithm | ||
| 58 | |||
| 59 | 4) Set Disksize | ||
| 46 | Set disk size by writing the value to sysfs node 'disksize'. | 60 | Set disk size by writing the value to sysfs node 'disksize'. |
| 47 | The value can be either in bytes or you can use mem suffixes. | 61 | The value can be either in bytes or you can use mem suffixes. |
| 48 | Examples: | 62 | Examples: |
| @@ -59,14 +73,14 @@ There is little point creating a zram of greater than twice the size of memory | |||
| 59 | since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the | 73 | since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the |
| 60 | size of the disk when not in use so a huge zram is wasteful. | 74 | size of the disk when not in use so a huge zram is wasteful. |
| 61 | 75 | ||
| 62 | 4) Activate: | 76 | 5) Activate: |
| 63 | mkswap /dev/zram0 | 77 | mkswap /dev/zram0 |
| 64 | swapon /dev/zram0 | 78 | swapon /dev/zram0 |
| 65 | 79 | ||
| 66 | mkfs.ext4 /dev/zram1 | 80 | mkfs.ext4 /dev/zram1 |
| 67 | mount /dev/zram1 /tmp | 81 | mount /dev/zram1 /tmp |
| 68 | 82 | ||
| 69 | 5) Stats: | 83 | 6) Stats: |
| 70 | Per-device statistics are exported as various nodes under | 84 | Per-device statistics are exported as various nodes under |
| 71 | /sys/block/zram<id>/ | 85 | /sys/block/zram<id>/ |
| 72 | disksize | 86 | disksize |
| @@ -81,11 +95,11 @@ size of the disk when not in use so a huge zram is wasteful. | |||
| 81 | compr_data_size | 95 | compr_data_size |
| 82 | mem_used_total | 96 | mem_used_total |
| 83 | 97 | ||
| 84 | 6) Deactivate: | 98 | 7) Deactivate: |
| 85 | swapoff /dev/zram0 | 99 | swapoff /dev/zram0 |
| 86 | umount /dev/zram1 | 100 | umount /dev/zram1 |
| 87 | 101 | ||
| 88 | 7) Reset: | 102 | 8) Reset: |
| 89 | Write any positive value to 'reset' sysfs node | 103 | Write any positive value to 'reset' sysfs node |
| 90 | echo 1 > /sys/block/zram0/reset | 104 | echo 1 > /sys/block/zram0/reset |
| 91 | echo 1 > /sys/block/zram1/reset | 105 | echo 1 > /sys/block/zram1/reset |
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index ac276f79f21c..aad533a8bc55 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c | |||
| @@ -39,11 +39,20 @@ struct zcomp_strm_multi { | |||
| 39 | wait_queue_head_t strm_wait; | 39 | wait_queue_head_t strm_wait; |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | static struct zcomp_backend *backends[] = { | ||
| 43 | &zcomp_lzo, | ||
| 44 | NULL | ||
| 45 | }; | ||
| 46 | |||
| 42 | static struct zcomp_backend *find_backend(const char *compress) | 47 | static struct zcomp_backend *find_backend(const char *compress) |
| 43 | { | 48 | { |
| 44 | if (strncmp(compress, "lzo", 3) == 0) | 49 | int i = 0; |
| 45 | return &zcomp_lzo; | 50 | while (backends[i]) { |
| 46 | return NULL; | 51 | if (sysfs_streq(compress, backends[i]->name)) |
| 52 | break; | ||
| 53 | i++; | ||
| 54 | } | ||
| 55 | return backends[i]; | ||
| 47 | } | 56 | } |
| 48 | 57 | ||
| 49 | static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm) | 58 | static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm) |
| @@ -251,6 +260,23 @@ static int zcomp_strm_single_create(struct zcomp *comp) | |||
| 251 | return 0; | 260 | return 0; |
| 252 | } | 261 | } |
| 253 | 262 | ||
| 263 | /* show available compressors */ | ||
| 264 | ssize_t zcomp_available_show(const char *comp, char *buf) | ||
| 265 | { | ||
| 266 | ssize_t sz = 0; | ||
| 267 | int i = 0; | ||
| 268 | |||
| 269 | while (backends[i]) { | ||
| 270 | if (sysfs_streq(comp, backends[i]->name)) | ||
| 271 | sz += sprintf(buf + sz, "[%s] ", backends[i]->name); | ||
| 272 | else | ||
| 273 | sz += sprintf(buf + sz, "%s ", backends[i]->name); | ||
| 274 | i++; | ||
| 275 | } | ||
| 276 | sz += sprintf(buf + sz, "\n"); | ||
| 277 | return sz; | ||
| 278 | } | ||
| 279 | |||
| 254 | int zcomp_set_max_streams(struct zcomp *comp, int num_strm) | 280 | int zcomp_set_max_streams(struct zcomp *comp, int num_strm) |
| 255 | { | 281 | { |
| 256 | return comp->set_max_streams(comp, num_strm); | 282 | return comp->set_max_streams(comp, num_strm); |
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h index bd11d59c5dd1..8b8997f8613b 100644 --- a/drivers/block/zram/zcomp.h +++ b/drivers/block/zram/zcomp.h | |||
| @@ -50,6 +50,8 @@ struct zcomp { | |||
| 50 | void (*destroy)(struct zcomp *comp); | 50 | void (*destroy)(struct zcomp *comp); |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | ssize_t zcomp_available_show(const char *comp, char *buf); | ||
| 54 | |||
| 53 | struct zcomp *zcomp_create(const char *comp, int max_strm); | 55 | struct zcomp *zcomp_create(const char *comp, int max_strm); |
| 54 | void zcomp_destroy(struct zcomp *comp); | 56 | void zcomp_destroy(struct zcomp *comp); |
| 55 | 57 | ||
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 3a5f24c341dc..15d46f2e158c 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
| @@ -141,6 +141,34 @@ static ssize_t max_comp_streams_store(struct device *dev, | |||
| 141 | return len; | 141 | return len; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | static ssize_t comp_algorithm_show(struct device *dev, | ||
| 145 | struct device_attribute *attr, char *buf) | ||
| 146 | { | ||
| 147 | size_t sz; | ||
| 148 | struct zram *zram = dev_to_zram(dev); | ||
| 149 | |||
| 150 | down_read(&zram->init_lock); | ||
| 151 | sz = zcomp_available_show(zram->compressor, buf); | ||
| 152 | up_read(&zram->init_lock); | ||
| 153 | |||
| 154 | return sz; | ||
| 155 | } | ||
| 156 | |||
| 157 | static ssize_t comp_algorithm_store(struct device *dev, | ||
| 158 | struct device_attribute *attr, const char *buf, size_t len) | ||
| 159 | { | ||
| 160 | struct zram *zram = dev_to_zram(dev); | ||
| 161 | down_write(&zram->init_lock); | ||
| 162 | if (init_done(zram)) { | ||
| 163 | up_write(&zram->init_lock); | ||
| 164 | pr_info("Can't change algorithm for initialized device\n"); | ||
| 165 | return -EBUSY; | ||
| 166 | } | ||
| 167 | strlcpy(zram->compressor, buf, sizeof(zram->compressor)); | ||
| 168 | up_write(&zram->init_lock); | ||
| 169 | return len; | ||
| 170 | } | ||
| 171 | |||
| 144 | /* flag operations needs meta->tb_lock */ | 172 | /* flag operations needs meta->tb_lock */ |
| 145 | static int zram_test_flag(struct zram_meta *meta, u32 index, | 173 | static int zram_test_flag(struct zram_meta *meta, u32 index, |
| 146 | enum zram_pageflags flag) | 174 | enum zram_pageflags flag) |
| @@ -572,10 +600,10 @@ static ssize_t disksize_store(struct device *dev, | |||
| 572 | goto out_free_meta; | 600 | goto out_free_meta; |
| 573 | } | 601 | } |
| 574 | 602 | ||
| 575 | zram->comp = zcomp_create(default_compressor, zram->max_comp_streams); | 603 | zram->comp = zcomp_create(zram->compressor, zram->max_comp_streams); |
| 576 | if (!zram->comp) { | 604 | if (!zram->comp) { |
| 577 | pr_info("Cannot initialise %s compressing backend\n", | 605 | pr_info("Cannot initialise %s compressing backend\n", |
| 578 | default_compressor); | 606 | zram->compressor); |
| 579 | err = -EINVAL; | 607 | err = -EINVAL; |
| 580 | goto out_free_meta; | 608 | goto out_free_meta; |
| 581 | } | 609 | } |
| @@ -735,6 +763,8 @@ static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL); | |||
| 735 | static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); | 763 | static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); |
| 736 | static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR, | 764 | static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR, |
| 737 | max_comp_streams_show, max_comp_streams_store); | 765 | max_comp_streams_show, max_comp_streams_store); |
| 766 | static DEVICE_ATTR(comp_algorithm, S_IRUGO | S_IWUSR, | ||
| 767 | comp_algorithm_show, comp_algorithm_store); | ||
| 738 | 768 | ||
| 739 | ZRAM_ATTR_RO(num_reads); | 769 | ZRAM_ATTR_RO(num_reads); |
| 740 | ZRAM_ATTR_RO(num_writes); | 770 | ZRAM_ATTR_RO(num_writes); |
| @@ -760,6 +790,7 @@ static struct attribute *zram_disk_attrs[] = { | |||
| 760 | &dev_attr_compr_data_size.attr, | 790 | &dev_attr_compr_data_size.attr, |
| 761 | &dev_attr_mem_used_total.attr, | 791 | &dev_attr_mem_used_total.attr, |
| 762 | &dev_attr_max_comp_streams.attr, | 792 | &dev_attr_max_comp_streams.attr, |
| 793 | &dev_attr_comp_algorithm.attr, | ||
| 763 | NULL, | 794 | NULL, |
| 764 | }; | 795 | }; |
| 765 | 796 | ||
| @@ -820,7 +851,7 @@ static int create_device(struct zram *zram, int device_id) | |||
| 820 | pr_warn("Error creating sysfs group"); | 851 | pr_warn("Error creating sysfs group"); |
| 821 | goto out_free_disk; | 852 | goto out_free_disk; |
| 822 | } | 853 | } |
| 823 | 854 | strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor)); | |
| 824 | zram->meta = NULL; | 855 | zram->meta = NULL; |
| 825 | zram->max_comp_streams = 1; | 856 | zram->max_comp_streams = 1; |
| 826 | return 0; | 857 | return 0; |
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index ccf36d11755a..7f21c145e317 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h | |||
| @@ -101,5 +101,6 @@ struct zram { | |||
| 101 | u64 disksize; /* bytes */ | 101 | u64 disksize; /* bytes */ |
| 102 | int max_comp_streams; | 102 | int max_comp_streams; |
| 103 | struct zram_stats stats; | 103 | struct zram_stats stats; |
| 104 | char compressor[10]; | ||
| 104 | }; | 105 | }; |
| 105 | #endif | 106 | #endif |
