diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-block-zram | 10 | ||||
-rw-r--r-- | Documentation/blockdev/zram.txt | 1 | ||||
-rw-r--r-- | drivers/block/zram/zram_drv.c | 60 | ||||
-rw-r--r-- | drivers/block/zram/zram_drv.h | 1 |
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 | ||
123 | What: /sys/block/zram<id>/mem_used_max | ||
124 | Date: August 2014 | ||
125 | Contact: Minchan Kim <minchan@kernel.org> | ||
126 | Description: | ||
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 | |||
123 | What: /sys/block/zram<id>/mem_limit | 133 | What: /sys/block/zram<id>/mem_limit |
124 | Date: August 2014 | 134 | Date: August 2014 |
125 | Contact: Minchan Kim <minchan@kernel.org> | 135 | Contact: 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 | ||
115 | 8) Deactivate: | 116 | 8) 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 | ||
156 | static 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 | |||
170 | static 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 | |||
156 | static ssize_t max_comp_streams_store(struct device *dev, | 191 | static 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 | ||
503 | static 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 | |||
468 | static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | 518 | static 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); | |||
901 | static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); | 954 | static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); |
902 | static DEVICE_ATTR(mem_limit, S_IRUGO | S_IWUSR, mem_limit_show, | 955 | static DEVICE_ATTR(mem_limit, S_IRUGO | S_IWUSR, mem_limit_show, |
903 | mem_limit_store); | 956 | mem_limit_store); |
957 | static DEVICE_ATTR(mem_used_max, S_IRUGO | S_IWUSR, mem_used_max_show, | ||
958 | mem_used_max_store); | ||
904 | static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR, | 959 | static 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); |
906 | static DEVICE_ATTR(comp_algorithm, S_IRUGO | S_IWUSR, | 961 | static 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 | ||
95 | struct zram_meta { | 96 | struct zram_meta { |