diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-block-zram | 9 | ||||
-rw-r--r-- | Documentation/blockdev/zram.txt | 24 | ||||
-rw-r--r-- | drivers/block/zram/zram_drv.c | 45 | ||||
-rw-r--r-- | drivers/block/zram/zram_drv.h | 5 |
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 | |||
123 | What: /sys/block/zram<id>/mem_limit | ||
124 | Date: August 2014 | ||
125 | Contact: Minchan Kim <minchan@kernel.org> | ||
126 | Description: | ||
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 | |||
74 | since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the | 74 | since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the |
75 | size of the disk when not in use so a huge zram is wasteful. | 75 | size of the disk when not in use so a huge zram is wasteful. |
76 | 76 | ||
77 | 5) Activate: | 77 | 5) 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 | |||
93 | 6) 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 | ||
84 | 6) Stats: | 100 | 7) 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 | ||
99 | 7) Deactivate: | 115 | 8) Deactivate: |
100 | swapoff /dev/zram0 | 116 | swapoff /dev/zram0 |
101 | umount /dev/zram1 | 117 | umount /dev/zram1 |
102 | 118 | ||
103 | 8) Reset: | 119 | 9) 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 | ||
125 | static 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 | |||
138 | static 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 | |||
125 | static ssize_t max_comp_streams_store(struct device *dev, | 156 | static 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); | |||
857 | static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store); | 899 | static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store); |
858 | static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL); | 900 | static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL); |
859 | static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); | 901 | 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, | ||
903 | mem_limit_store); | ||
860 | static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR, | 904 | static 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); |
862 | static DEVICE_ATTR(comp_algorithm, S_IRUGO | S_IWUSR, | 906 | static 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 |