aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/zram
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 /drivers/block/zram
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>
Diffstat (limited to 'drivers/block/zram')
-rw-r--r--drivers/block/zram/zram_drv.c45
-rw-r--r--drivers/block/zram/zram_drv.h5
2 files changed, 50 insertions, 0 deletions
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