aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMinchan Kim <minchan@kernel.org>2014-10-09 18:29:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-09 22:26:02 -0400
commit461a8eee6af3b55745be64bea403ed0b743563cf (patch)
treea1bea4ab73525d7f3f56c437b86843b04cb0e03c
parent9ada9da9573f3460b156b7755c093e30b258eacb (diff)
zram: report maximum used memory
Normally, zram user could get maximum memory usage zram consumed via polling mem_used_total with sysfs in userspace. But it has a critical problem because user can miss peak memory usage during update inverval of polling. For avoiding that, user should poll it with shorter interval(ie, 0.0000000001s) with mlocking to avoid page fault delay when memory pressure is heavy. It would be troublesome. This patch adds new knob "mem_used_max" so user could see the maximum memory usage easily via reading the knob and reset it via "echo 0 > /sys/block/zram0/mem_used_max". Signed-off-by: Minchan Kim <minchan@kernel.org> Reviewed-by: 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> Reviewed-by: David Horner <ds2horner@gmail.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> 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-zram10
-rw-r--r--Documentation/blockdev/zram.txt1
-rw-r--r--drivers/block/zram/zram_drv.c60
-rw-r--r--drivers/block/zram/zram_drv.h1
4 files changed, 70 insertions, 2 deletions
diff --git a/Documentation/ABI/testing/sysfs-block-zram b/Documentation/ABI/testing/sysfs-block-zram
index ea67fa3f3cff..b13dc993291f 100644
--- a/Documentation/ABI/testing/sysfs-block-zram
+++ b/Documentation/ABI/testing/sysfs-block-zram
@@ -120,6 +120,16 @@ Description:
120 statistic. 120 statistic.
121 Unit: bytes 121 Unit: bytes
122 122
123What: /sys/block/zram<id>/mem_used_max
124Date: August 2014
125Contact: Minchan Kim <minchan@kernel.org>
126Description:
127 The mem_used_max file is read/write and specifies the amount
128 of maximum memory zram have consumed to store compressed data.
129 For resetting the value, you should write "0". Otherwise,
130 you could see -EINVAL.
131 Unit: bytes
132
123What: /sys/block/zram<id>/mem_limit 133What: /sys/block/zram<id>/mem_limit
124Date: August 2014 134Date: August 2014
125Contact: Minchan Kim <minchan@kernel.org> 135Contact: Minchan Kim <minchan@kernel.org>
diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt
index 82c6a41116db..7fcf9c6592ec 100644
--- a/Documentation/blockdev/zram.txt
+++ b/Documentation/blockdev/zram.txt
@@ -111,6 +111,7 @@ size of the disk when not in use so a huge zram is wasteful.
111 orig_data_size 111 orig_data_size
112 compr_data_size 112 compr_data_size
113 mem_used_total 113 mem_used_total
114 mem_used_max
114 115
1158) Deactivate: 1168) Deactivate:
116 swapoff /dev/zram0 117 swapoff /dev/zram0
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 64b27cf9a583..d78b245bae06 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -153,6 +153,41 @@ static ssize_t mem_limit_store(struct device *dev,
153 return len; 153 return len;
154} 154}
155 155
156static ssize_t mem_used_max_show(struct device *dev,
157 struct device_attribute *attr, char *buf)
158{
159 u64 val = 0;
160 struct zram *zram = dev_to_zram(dev);
161
162 down_read(&zram->init_lock);
163 if (init_done(zram))
164 val = atomic_long_read(&zram->stats.max_used_pages);
165 up_read(&zram->init_lock);
166
167 return scnprintf(buf, PAGE_SIZE, "%llu\n", val << PAGE_SHIFT);
168}
169
170static ssize_t mem_used_max_store(struct device *dev,
171 struct device_attribute *attr, const char *buf, size_t len)
172{
173 int err;
174 unsigned long val;
175 struct zram *zram = dev_to_zram(dev);
176 struct zram_meta *meta = zram->meta;
177
178 err = kstrtoul(buf, 10, &val);
179 if (err || val != 0)
180 return -EINVAL;
181
182 down_read(&zram->init_lock);
183 if (init_done(zram))
184 atomic_long_set(&zram->stats.max_used_pages,
185 zs_get_total_pages(meta->mem_pool));
186 up_read(&zram->init_lock);
187
188 return len;
189}
190
156static ssize_t max_comp_streams_store(struct device *dev, 191static ssize_t max_comp_streams_store(struct device *dev,
157 struct device_attribute *attr, const char *buf, size_t len) 192 struct device_attribute *attr, const char *buf, size_t len)
158{ 193{
@@ -465,6 +500,21 @@ out_cleanup:
465 return ret; 500 return ret;
466} 501}
467 502
503static inline void update_used_max(struct zram *zram,
504 const unsigned long pages)
505{
506 int old_max, cur_max;
507
508 old_max = atomic_long_read(&zram->stats.max_used_pages);
509
510 do {
511 cur_max = old_max;
512 if (pages > cur_max)
513 old_max = atomic_long_cmpxchg(
514 &zram->stats.max_used_pages, cur_max, pages);
515 } while (old_max != cur_max);
516}
517
468static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, 518static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
469 int offset) 519 int offset)
470{ 520{
@@ -476,6 +526,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
476 struct zram_meta *meta = zram->meta; 526 struct zram_meta *meta = zram->meta;
477 struct zcomp_strm *zstrm; 527 struct zcomp_strm *zstrm;
478 bool locked = false; 528 bool locked = false;
529 unsigned long alloced_pages;
479 530
480 page = bvec->bv_page; 531 page = bvec->bv_page;
481 if (is_partial_io(bvec)) { 532 if (is_partial_io(bvec)) {
@@ -545,13 +596,15 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
545 goto out; 596 goto out;
546 } 597 }
547 598
548 if (zram->limit_pages && 599 alloced_pages = zs_get_total_pages(meta->mem_pool);
549 zs_get_total_pages(meta->mem_pool) > zram->limit_pages) { 600 if (zram->limit_pages && alloced_pages > zram->limit_pages) {
550 zs_free(meta->mem_pool, handle); 601 zs_free(meta->mem_pool, handle);
551 ret = -ENOMEM; 602 ret = -ENOMEM;
552 goto out; 603 goto out;
553 } 604 }
554 605
606 update_used_max(zram, alloced_pages);
607
555 cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_WO); 608 cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_WO);
556 609
557 if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) { 610 if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) {
@@ -901,6 +954,8 @@ static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
901static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); 954static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
902static DEVICE_ATTR(mem_limit, S_IRUGO | S_IWUSR, mem_limit_show, 955static DEVICE_ATTR(mem_limit, S_IRUGO | S_IWUSR, mem_limit_show,
903 mem_limit_store); 956 mem_limit_store);
957static DEVICE_ATTR(mem_used_max, S_IRUGO | S_IWUSR, mem_used_max_show,
958 mem_used_max_store);
904static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR, 959static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR,
905 max_comp_streams_show, max_comp_streams_store); 960 max_comp_streams_show, max_comp_streams_store);
906static DEVICE_ATTR(comp_algorithm, S_IRUGO | S_IWUSR, 961static DEVICE_ATTR(comp_algorithm, S_IRUGO | S_IWUSR,
@@ -930,6 +985,7 @@ static struct attribute *zram_disk_attrs[] = {
930 &dev_attr_compr_data_size.attr, 985 &dev_attr_compr_data_size.attr,
931 &dev_attr_mem_used_total.attr, 986 &dev_attr_mem_used_total.attr,
932 &dev_attr_mem_limit.attr, 987 &dev_attr_mem_limit.attr,
988 &dev_attr_mem_used_max.attr,
933 &dev_attr_max_comp_streams.attr, 989 &dev_attr_max_comp_streams.attr,
934 &dev_attr_comp_algorithm.attr, 990 &dev_attr_comp_algorithm.attr,
935 NULL, 991 NULL,
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index b7aa9c21553f..c6ee271317f5 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -90,6 +90,7 @@ struct zram_stats {
90 atomic64_t notify_free; /* no. of swap slot free notifications */ 90 atomic64_t notify_free; /* no. of swap slot free notifications */
91 atomic64_t zero_pages; /* no. of zero filled pages */ 91 atomic64_t zero_pages; /* no. of zero filled pages */
92 atomic64_t pages_stored; /* no. of pages currently stored */ 92 atomic64_t pages_stored; /* no. of pages currently stored */
93 atomic_long_t max_used_pages; /* no. of maximum pages stored */
93}; 94};
94 95
95struct zram_meta { 96struct zram_meta {