Commit e46b8a030d76d3c94156c545c3f4c3676d813435
Committed by
Linus Torvalds
1 parent
fe8eb122c8
Exists in
master
and in
13 other branches
zram: make compression algorithm selection possible
Add and document `comp_algorithm' device attribute. This attribute allows to show supported compression and currently selected compression algorithms: cat /sys/block/zram0/comp_algorithm [lzo] lz4 and change selected compression algorithm: echo lzo > /sys/block/zram0/comp_algorithm Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Acked-by: Minchan Kim <minchan@kernel.org> Cc: Jerome Marchand <jmarchan@redhat.com> Cc: Nitin Gupta <ngupta@vflare.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 6 changed files with 93 additions and 11 deletions Side-by-side Diff
Documentation/ABI/testing/sysfs-block-zram
... | ... | @@ -65,6 +65,14 @@ |
65 | 65 | number of backend's zcomp_strm compression streams (number of |
66 | 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 | 76 | What: /sys/block/zram<id>/notify_free |
69 | 77 | Date: August 2010 |
70 | 78 | Contact: Nitin Gupta <ngupta@vflare.org> |
Documentation/blockdev/zram.txt
... | ... | @@ -42,7 +42,21 @@ |
42 | 42 | as a special case and does not support dynamic max_comp_streams. Only multi |
43 | 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 | 60 | Set disk size by writing the value to sysfs node 'disksize'. |
47 | 61 | The value can be either in bytes or you can use mem suffixes. |
48 | 62 | Examples: |
49 | 63 | |
... | ... | @@ -59,14 +73,14 @@ |
59 | 73 | since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the |
60 | 74 | size of the disk when not in use so a huge zram is wasteful. |
61 | 75 | |
62 | -4) Activate: | |
76 | +5) Activate: | |
63 | 77 | mkswap /dev/zram0 |
64 | 78 | swapon /dev/zram0 |
65 | 79 | |
66 | 80 | mkfs.ext4 /dev/zram1 |
67 | 81 | mount /dev/zram1 /tmp |
68 | 82 | |
69 | -5) Stats: | |
83 | +6) Stats: | |
70 | 84 | Per-device statistics are exported as various nodes under |
71 | 85 | /sys/block/zram<id>/ |
72 | 86 | disksize |
73 | 87 | |
... | ... | @@ -81,11 +95,11 @@ |
81 | 95 | compr_data_size |
82 | 96 | mem_used_total |
83 | 97 | |
84 | -6) Deactivate: | |
98 | +7) Deactivate: | |
85 | 99 | swapoff /dev/zram0 |
86 | 100 | umount /dev/zram1 |
87 | 101 | |
88 | -7) Reset: | |
102 | +8) Reset: | |
89 | 103 | Write any positive value to 'reset' sysfs node |
90 | 104 | echo 1 > /sys/block/zram0/reset |
91 | 105 | echo 1 > /sys/block/zram1/reset |
drivers/block/zram/zcomp.c
... | ... | @@ -39,11 +39,20 @@ |
39 | 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 | 47 | static struct zcomp_backend *find_backend(const char *compress) |
43 | 48 | { |
44 | - if (strncmp(compress, "lzo", 3) == 0) | |
45 | - return &zcomp_lzo; | |
46 | - return NULL; | |
49 | + int i = 0; | |
50 | + while (backends[i]) { | |
51 | + if (sysfs_streq(compress, backends[i]->name)) | |
52 | + break; | |
53 | + i++; | |
54 | + } | |
55 | + return backends[i]; | |
47 | 56 | } |
48 | 57 | |
49 | 58 | static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm) |
... | ... | @@ -249,6 +258,23 @@ |
249 | 258 | return -ENOMEM; |
250 | 259 | } |
251 | 260 | return 0; |
261 | +} | |
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; | |
252 | 278 | } |
253 | 279 | |
254 | 280 | int zcomp_set_max_streams(struct zcomp *comp, int num_strm) |
drivers/block/zram/zcomp.h
drivers/block/zram/zram_drv.c
... | ... | @@ -141,6 +141,34 @@ |
141 | 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 | 172 | /* flag operations needs meta->tb_lock */ |
145 | 173 | static int zram_test_flag(struct zram_meta *meta, u32 index, |
146 | 174 | enum zram_pageflags flag) |
147 | 175 | |
... | ... | @@ -572,10 +600,10 @@ |
572 | 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 | 604 | if (!zram->comp) { |
577 | 605 | pr_info("Cannot initialise %s compressing backend\n", |
578 | - default_compressor); | |
606 | + zram->compressor); | |
579 | 607 | err = -EINVAL; |
580 | 608 | goto out_free_meta; |
581 | 609 | } |
... | ... | @@ -735,6 +763,8 @@ |
735 | 763 | static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); |
736 | 764 | static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR, |
737 | 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 | 769 | ZRAM_ATTR_RO(num_reads); |
740 | 770 | ZRAM_ATTR_RO(num_writes); |
... | ... | @@ -760,6 +790,7 @@ |
760 | 790 | &dev_attr_compr_data_size.attr, |
761 | 791 | &dev_attr_mem_used_total.attr, |
762 | 792 | &dev_attr_max_comp_streams.attr, |
793 | + &dev_attr_comp_algorithm.attr, | |
763 | 794 | NULL, |
764 | 795 | }; |
765 | 796 | |
... | ... | @@ -820,7 +851,7 @@ |
820 | 851 | pr_warn("Error creating sysfs group"); |
821 | 852 | goto out_free_disk; |
822 | 853 | } |
823 | - | |
854 | + strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor)); | |
824 | 855 | zram->meta = NULL; |
825 | 856 | zram->max_comp_streams = 1; |
826 | 857 | return 0; |