aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMinchan Kim <minchan@kernel.org>2014-10-09 18:29:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-09 22:26:02 -0400
commit9ada9da9573f3460b156b7755c093e30b258eacb (patch)
tree45d38673aa9bc81b99131a3a3c5e1e97292bb5f5
parent722cdc17232f0f684011407f7cf3c40d39457971 (diff)
zram: zram memory size limitation
Since zram has no control feature to limit memory usage, it makes hard to manage system memrory. This patch adds new knob "mem_limit" via sysfs to set up the a limit so that zram could fail allocation once it reaches the limit. In addition, user could change the limit in runtime so that he could manage the memory more dynamically. Initial state is no limit so it doesn't break old behavior. [akpm@linux-foundation.org: fix typo, per Sergey] Signed-off-by: Minchan Kim <minchan@kernel.org> Cc: Dan Streetman <ddstreet@ieee.org> Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Cc: Jerome Marchand <jmarchan@redhat.com> Cc: <juno.choi@lge.com> Cc: <seungho1.park@lge.com> Cc: Luigi Semenzato <semenzato@google.com> Cc: Nitin Gupta <ngupta@vflare.org> Cc: Seth Jennings <sjennings@variantweb.net> Cc: David Horner <ds2horner@gmail.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Minchan Kim <minchan@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/ABI/testing/sysfs-block-zram9
-rw-r--r--Documentation/blockdev/zram.txt24
-rw-r--r--drivers/block/zram/zram_drv.c45
-rw-r--r--drivers/block/zram/zram_drv.h5
4 files changed, 79 insertions, 4 deletions
diff --git a/Documentation/ABI/testing/sysfs-block-zram b/Documentation/ABI/testing/sysfs-block-zram
index 70ec992514d0..ea67fa3f3cff 100644
--- a/Documentation/ABI/testing/sysfs-block-zram
+++ b/Documentation/ABI/testing/sysfs-block-zram
@@ -119,3 +119,12 @@ Description:
119 efficiency can be calculated using compr_data_size and this 119 efficiency can be calculated using compr_data_size and this
120 statistic. 120 statistic.
121 Unit: bytes 121 Unit: bytes
122
123What: /sys/block/zram<id>/mem_limit
124Date: August 2014
125Contact: Minchan Kim <minchan@kernel.org>
126Description:
127 The mem_limit file is read/write and specifies the maximum
128 amount of memory ZRAM can use to store the compressed data. The
129 limit could be changed in run time and "0" means disable the
130 limit. No limit is the initial state. Unit: bytes
diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt
index 0595c3f56ccf..82c6a41116db 100644
--- a/Documentation/blockdev/zram.txt
+++ b/Documentation/blockdev/zram.txt
@@ -74,14 +74,30 @@ There is little point creating a zram of greater than twice the size of memory
74since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the 74since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the
75size of the disk when not in use so a huge zram is wasteful. 75size of the disk when not in use so a huge zram is wasteful.
76 76
775) Activate: 775) Set memory limit: Optional
78 Set memory limit by writing the value to sysfs node 'mem_limit'.
79 The value can be either in bytes or you can use mem suffixes.
80 In addition, you could change the value in runtime.
81 Examples:
82 # limit /dev/zram0 with 50MB memory
83 echo $((50*1024*1024)) > /sys/block/zram0/mem_limit
84
85 # Using mem suffixes
86 echo 256K > /sys/block/zram0/mem_limit
87 echo 512M > /sys/block/zram0/mem_limit
88 echo 1G > /sys/block/zram0/mem_limit
89
90 # To disable memory limit
91 echo 0 > /sys/block/zram0/mem_limit
92
936) Activate:
78 mkswap /dev/zram0 94 mkswap /dev/zram0
79 swapon /dev/zram0 95 swapon /dev/zram0
80 96
81 mkfs.ext4 /dev/zram1 97 mkfs.ext4 /dev/zram1
82 mount /dev/zram1 /tmp 98 mount /dev/zram1 /tmp
83 99
846) Stats: 1007) Stats:
85 Per-device statistics are exported as various nodes under 101 Per-device statistics are exported as various nodes under
86 /sys/block/zram<id>/ 102 /sys/block/zram<id>/
87 disksize 103 disksize
@@ -96,11 +112,11 @@ size of the disk when not in use so a huge zram is wasteful.
96 compr_data_size 112 compr_data_size
97 mem_used_total 113 mem_used_total
98 114
997) Deactivate: 1158) Deactivate:
100 swapoff /dev/zram0 116 swapoff /dev/zram0
101 umount /dev/zram1 117 umount /dev/zram1
102 118
1038) Reset: 1199) Reset:
104 Write any positive value to 'reset' sysfs node 120 Write any positive value to 'reset' sysfs node
105 echo 1 > /sys/block/zram0/reset 121 echo 1 > /sys/block/zram0/reset
106 echo 1 > /sys/block/zram1/reset 122 echo 1 > /sys/block/zram1/reset
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index f0b8b30a7128..64b27cf9a583 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -122,6 +122,37 @@ static ssize_t max_comp_streams_show(struct device *dev,
122 return scnprintf(buf, PAGE_SIZE, "%d\n", val); 122 return scnprintf(buf, PAGE_SIZE, "%d\n", val);
123} 123}
124 124
125static ssize_t mem_limit_show(struct device *dev,
126 struct device_attribute *attr, char *buf)
127{
128 u64 val;
129 struct zram *zram = dev_to_zram(dev);
130
131 down_read(&zram->init_lock);
132 val = zram->limit_pages;
133 up_read(&zram->init_lock);
134
135 return scnprintf(buf, PAGE_SIZE, "%llu\n", val << PAGE_SHIFT);
136}
137
138static ssize_t mem_limit_store(struct device *dev,
139 struct device_attribute *attr, const char *buf, size_t len)
140{
141 u64 limit;
142 char *tmp;
143 struct zram *zram = dev_to_zram(dev);
144
145 limit = memparse(buf, &tmp);
146 if (buf == tmp) /* no chars parsed, invalid input */
147 return -EINVAL;
148
149 down_write(&zram->init_lock);
150 zram->limit_pages = PAGE_ALIGN(limit) >> PAGE_SHIFT;
151 up_write(&zram->init_lock);
152
153 return len;
154}
155
125static ssize_t max_comp_streams_store(struct device *dev, 156static ssize_t max_comp_streams_store(struct device *dev,
126 struct device_attribute *attr, const char *buf, size_t len) 157 struct device_attribute *attr, const char *buf, size_t len)
127{ 158{
@@ -513,6 +544,14 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
513 ret = -ENOMEM; 544 ret = -ENOMEM;
514 goto out; 545 goto out;
515 } 546 }
547
548 if (zram->limit_pages &&
549 zs_get_total_pages(meta->mem_pool) > zram->limit_pages) {
550 zs_free(meta->mem_pool, handle);
551 ret = -ENOMEM;
552 goto out;
553 }
554
516 cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_WO); 555 cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_WO);
517 556
518 if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) { 557 if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) {
@@ -617,6 +656,9 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
617 struct zram_meta *meta; 656 struct zram_meta *meta;
618 657
619 down_write(&zram->init_lock); 658 down_write(&zram->init_lock);
659
660 zram->limit_pages = 0;
661
620 if (!init_done(zram)) { 662 if (!init_done(zram)) {
621 up_write(&zram->init_lock); 663 up_write(&zram->init_lock);
622 return; 664 return;
@@ -857,6 +899,8 @@ static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
857static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store); 899static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
858static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL); 900static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
859static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); 901static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
902static DEVICE_ATTR(mem_limit, S_IRUGO | S_IWUSR, mem_limit_show,
903 mem_limit_store);
860static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR, 904static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR,
861 max_comp_streams_show, max_comp_streams_store); 905 max_comp_streams_show, max_comp_streams_store);
862static DEVICE_ATTR(comp_algorithm, S_IRUGO | S_IWUSR, 906static DEVICE_ATTR(comp_algorithm, S_IRUGO | S_IWUSR,
@@ -885,6 +929,7 @@ static struct attribute *zram_disk_attrs[] = {
885 &dev_attr_orig_data_size.attr, 929 &dev_attr_orig_data_size.attr,
886 &dev_attr_compr_data_size.attr, 930 &dev_attr_compr_data_size.attr,
887 &dev_attr_mem_used_total.attr, 931 &dev_attr_mem_used_total.attr,
932 &dev_attr_mem_limit.attr,
888 &dev_attr_max_comp_streams.attr, 933 &dev_attr_max_comp_streams.attr,
889 &dev_attr_comp_algorithm.attr, 934 &dev_attr_comp_algorithm.attr,
890 NULL, 935 NULL,
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index e0f725c87cc6..b7aa9c21553f 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -112,6 +112,11 @@ struct zram {
112 u64 disksize; /* bytes */ 112 u64 disksize; /* bytes */
113 int max_comp_streams; 113 int max_comp_streams;
114 struct zram_stats stats; 114 struct zram_stats stats;
115 /*
116 * the number of pages zram can consume for storing compressed data
117 */
118 unsigned long limit_pages;
119
115 char compressor[10]; 120 char compressor[10];
116}; 121};
117#endif 122#endif