Commit e46b8a030d76d3c94156c545c3f4c3676d813435

Authored by Sergey Senozhatsky
Committed by Linus Torvalds
1 parent fe8eb122c8

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
... ... @@ -50,6 +50,8 @@
50 50 void (*destroy)(struct zcomp *comp);
51 51 };
52 52  
  53 +ssize_t zcomp_available_show(const char *comp, char *buf);
  54 +
53 55 struct zcomp *zcomp_create(const char *comp, int max_strm);
54 56 void zcomp_destroy(struct zcomp *comp);
55 57  
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;
drivers/block/zram/zram_drv.h
... ... @@ -101,6 +101,7 @@
101 101 u64 disksize; /* bytes */
102 102 int max_comp_streams;
103 103 struct zram_stats stats;
  104 + char compressor[10];
104 105 };
105 106 #endif