All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <20140806065253.GC3796@bbox>

diff --git a/a/1.txt b/N1/1.txt
index f962518..ab2f599 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -12,3 +12,173 @@ On Tue, Aug 05, 2014 at 10:16:15PM +0900, Sergey Senozhatsky wrote:
 > yes, I think this one is better.
 > 
 > 	-ss
+
+>From 279c406b5a8eabd03edca55490ec92b539b39c76 Mon Sep 17 00:00:00 2001
+From: Minchan Kim <minchan@kernel.org>
+Date: Tue, 5 Aug 2014 16:24:57 +0900
+Subject: [PATCH] zram: limit memory size for zram
+
+I have received a request several time from zram users.
+They want to limit memory size for zram because zram can consume
+lot of memory on system without limit so it makes memory management
+control hard.
+
+This patch adds new knob to limit memory of zram.
+
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+---
+ Documentation/blockdev/zram.txt |  1 +
+ drivers/block/zram/zram_drv.c   | 39 +++++++++++++++++++++++++++++++++++++--
+ include/linux/zsmalloc.h        |  2 ++
+ mm/zsmalloc.c                   | 24 ++++++++++++++++++++++++
+ 4 files changed, 64 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt
+index d24534bee763..fcb0561dfe2e 100644
+--- a/Documentation/blockdev/zram.txt
++++ b/Documentation/blockdev/zram.txt
+@@ -96,6 +96,7 @@ size of the disk when not in use so a huge zram is wasteful.
+ 		compr_data_size
+ 		mem_used_total
+ 		mem_used_max
++		mem_limit
+ 
+ 7) Deactivate:
+ 	swapoff /dev/zram0
+diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
+index a4d637b4db7d..069e81ef0c17 100644
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -137,6 +137,41 @@ static ssize_t max_comp_streams_show(struct device *dev,
+ 	return scnprintf(buf, PAGE_SIZE, "%d\n", val);
+ }
+ 
++static ssize_t mem_limit_show(struct device *dev,
++		struct device_attribute *attr, char *buf)
++{
++	u64 val = 0;
++	struct zram *zram = dev_to_zram(dev);
++	struct zram_meta *meta = zram->meta;
++
++	down_read(&zram->init_lock);
++	if (init_done(zram))
++		val = zs_get_limit_size_bytes(meta->mem_pool);
++	up_read(&zram->init_lock);
++
++	return scnprintf(buf, PAGE_SIZE, "%llu\n", val);
++}
++
++static ssize_t mem_limit_store(struct device *dev,
++		struct device_attribute *attr, const char *buf, size_t len)
++{
++	int ret;
++	u64 limit;
++	struct zram *zram = dev_to_zram(dev);
++	struct zram_meta *meta = zram->meta;
++
++	ret = kstrtoull(buf, 0, &limit);
++	if (ret < 0)
++		return ret;
++
++	down_write(&zram->init_lock);
++	if (init_done(zram))
++		zs_set_limit_size_bytes(meta->mem_pool, limit);
++	up_write(&zram->init_lock);
++	ret = len;
++	return ret;
++}
++
+ static ssize_t max_comp_streams_store(struct device *dev,
+ 		struct device_attribute *attr, const char *buf, size_t len)
+ {
+@@ -506,8 +541,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
+ 
+ 	handle = zs_malloc(meta->mem_pool, clen);
+ 	if (!handle) {
+-		pr_info("Error allocating memory for compressed page: %u, size=%zu\n",
+-			index, clen);
+ 		ret = -ENOMEM;
+ 		goto out;
+ 	}
+@@ -854,6 +887,7 @@ static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
+ static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);
+ static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);
+ static DEVICE_ATTR(mem_used_max, S_IRUGO, mem_used_max_show, NULL);
++static DEVICE_ATTR(mem_limit, S_IRUGO, mem_limit_show, mem_limit_store);
+ static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR,
+ 		max_comp_streams_show, max_comp_streams_store);
+ static DEVICE_ATTR(comp_algorithm, S_IRUGO | S_IWUSR,
+@@ -883,6 +917,7 @@ static struct attribute *zram_disk_attrs[] = {
+ 	&dev_attr_compr_data_size.attr,
+ 	&dev_attr_mem_used_total.attr,
+ 	&dev_attr_mem_used_max.attr,
++	&dev_attr_mem_limit.attr,
+ 	&dev_attr_max_comp_streams.attr,
+ 	&dev_attr_comp_algorithm.attr,
+ 	NULL,
+diff --git a/include/linux/zsmalloc.h b/include/linux/zsmalloc.h
+index fb087ca06a88..41122251a2d0 100644
+--- a/include/linux/zsmalloc.h
++++ b/include/linux/zsmalloc.h
+@@ -49,4 +49,6 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle);
+ u64 zs_get_total_size_bytes(struct zs_pool *pool);
+ u64 zs_get_max_size_bytes(struct zs_pool *pool);
+ 
++u64 zs_get_limit_size_bytes(struct zs_pool *pool);
++void zs_set_limit_size_bytes(struct zs_pool *pool, u64 limit);
+ #endif
+diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
+index 3b5be076268a..8ca51118cf2b 100644
+--- a/mm/zsmalloc.c
++++ b/mm/zsmalloc.c
+@@ -220,6 +220,7 @@ struct zs_pool {
+ 	gfp_t flags;	/* allocation flags used when growing pool */
+ 	unsigned long pages_allocated;
+ 	unsigned long max_pages_allocated;
++	unsigned long pages_limited;
+ };
+ 
+ /*
+@@ -940,6 +941,11 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size)
+ 
+ 	if (!first_page) {
+ 		spin_unlock(&class->lock);
++
++		if (pool->pages_limited && (pool->pages_limited <
++			pool->pages_allocated + class->pages_per_zspage))
++			return 0;
++
+ 		first_page = alloc_zspage(class, pool->flags);
+ 		if (unlikely(!first_page))
+ 			return 0;
+@@ -1132,6 +1138,24 @@ u64 zs_get_max_size_bytes(struct zs_pool *pool)
+ }
+ EXPORT_SYMBOL_GPL(zs_get_max_size_bytes);
+ 
++void zs_set_limit_size_bytes(struct zs_pool *pool, u64 limit)
++{
++	pool->pages_limited = round_down(limit, PAGE_SIZE) >> PAGE_SHIFT;
++}
++EXPORT_SYMBOL_GPL(zs_set_limit_size_bytes);
++
++u64 zs_get_limit_size_bytes(struct zs_pool *pool)
++{
++	u64 npages;
++
++	spin_lock(&pool->stat_lock);
++	npages = pool->pages_limited;
++	spin_unlock(&pool->stat_lock);
++	return npages << PAGE_SHIFT;
++
++}
++EXPORT_SYMBOL_GPL(zs_get_limit_size_bytes);
++
+ module_init(zs_init);
+ module_exit(zs_exit);
+ 
+-- 
+2.0.0
+
+-- 
+Kind regards,
+Minchan Kim
diff --git a/a/content_digest b/N1/content_digest
index f9b0504..6375ef2 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -28,6 +28,176 @@
  "> \n"
  "> yes, I think this one is better.\n"
  "> \n"
- "> \t-ss"
+ "> \t-ss\n"
+ "\n"
+ ">From 279c406b5a8eabd03edca55490ec92b539b39c76 Mon Sep 17 00:00:00 2001\n"
+ "From: Minchan Kim <minchan@kernel.org>\n"
+ "Date: Tue, 5 Aug 2014 16:24:57 +0900\n"
+ "Subject: [PATCH] zram: limit memory size for zram\n"
+ "\n"
+ "I have received a request several time from zram users.\n"
+ "They want to limit memory size for zram because zram can consume\n"
+ "lot of memory on system without limit so it makes memory management\n"
+ "control hard.\n"
+ "\n"
+ "This patch adds new knob to limit memory of zram.\n"
+ "\n"
+ "Signed-off-by: Minchan Kim <minchan@kernel.org>\n"
+ "---\n"
+ " Documentation/blockdev/zram.txt |  1 +\n"
+ " drivers/block/zram/zram_drv.c   | 39 +++++++++++++++++++++++++++++++++++++--\n"
+ " include/linux/zsmalloc.h        |  2 ++\n"
+ " mm/zsmalloc.c                   | 24 ++++++++++++++++++++++++\n"
+ " 4 files changed, 64 insertions(+), 2 deletions(-)\n"
+ "\n"
+ "diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt\n"
+ "index d24534bee763..fcb0561dfe2e 100644\n"
+ "--- a/Documentation/blockdev/zram.txt\n"
+ "+++ b/Documentation/blockdev/zram.txt\n"
+ "@@ -96,6 +96,7 @@ size of the disk when not in use so a huge zram is wasteful.\n"
+ " \t\tcompr_data_size\n"
+ " \t\tmem_used_total\n"
+ " \t\tmem_used_max\n"
+ "+\t\tmem_limit\n"
+ " \n"
+ " 7) Deactivate:\n"
+ " \tswapoff /dev/zram0\n"
+ "diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c\n"
+ "index a4d637b4db7d..069e81ef0c17 100644\n"
+ "--- a/drivers/block/zram/zram_drv.c\n"
+ "+++ b/drivers/block/zram/zram_drv.c\n"
+ "@@ -137,6 +137,41 @@ static ssize_t max_comp_streams_show(struct device *dev,\n"
+ " \treturn scnprintf(buf, PAGE_SIZE, \"%d\\n\", val);\n"
+ " }\n"
+ " \n"
+ "+static ssize_t mem_limit_show(struct device *dev,\n"
+ "+\t\tstruct device_attribute *attr, char *buf)\n"
+ "+{\n"
+ "+\tu64 val = 0;\n"
+ "+\tstruct zram *zram = dev_to_zram(dev);\n"
+ "+\tstruct zram_meta *meta = zram->meta;\n"
+ "+\n"
+ "+\tdown_read(&zram->init_lock);\n"
+ "+\tif (init_done(zram))\n"
+ "+\t\tval = zs_get_limit_size_bytes(meta->mem_pool);\n"
+ "+\tup_read(&zram->init_lock);\n"
+ "+\n"
+ "+\treturn scnprintf(buf, PAGE_SIZE, \"%llu\\n\", val);\n"
+ "+}\n"
+ "+\n"
+ "+static ssize_t mem_limit_store(struct device *dev,\n"
+ "+\t\tstruct device_attribute *attr, const char *buf, size_t len)\n"
+ "+{\n"
+ "+\tint ret;\n"
+ "+\tu64 limit;\n"
+ "+\tstruct zram *zram = dev_to_zram(dev);\n"
+ "+\tstruct zram_meta *meta = zram->meta;\n"
+ "+\n"
+ "+\tret = kstrtoull(buf, 0, &limit);\n"
+ "+\tif (ret < 0)\n"
+ "+\t\treturn ret;\n"
+ "+\n"
+ "+\tdown_write(&zram->init_lock);\n"
+ "+\tif (init_done(zram))\n"
+ "+\t\tzs_set_limit_size_bytes(meta->mem_pool, limit);\n"
+ "+\tup_write(&zram->init_lock);\n"
+ "+\tret = len;\n"
+ "+\treturn ret;\n"
+ "+}\n"
+ "+\n"
+ " static ssize_t max_comp_streams_store(struct device *dev,\n"
+ " \t\tstruct device_attribute *attr, const char *buf, size_t len)\n"
+ " {\n"
+ "@@ -506,8 +541,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,\n"
+ " \n"
+ " \thandle = zs_malloc(meta->mem_pool, clen);\n"
+ " \tif (!handle) {\n"
+ "-\t\tpr_info(\"Error allocating memory for compressed page: %u, size=%zu\\n\",\n"
+ "-\t\t\tindex, clen);\n"
+ " \t\tret = -ENOMEM;\n"
+ " \t\tgoto out;\n"
+ " \t}\n"
+ "@@ -854,6 +887,7 @@ static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);\n"
+ " static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL);\n"
+ " static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL);\n"
+ " static DEVICE_ATTR(mem_used_max, S_IRUGO, mem_used_max_show, NULL);\n"
+ "+static DEVICE_ATTR(mem_limit, S_IRUGO, mem_limit_show, mem_limit_store);\n"
+ " static DEVICE_ATTR(max_comp_streams, S_IRUGO | S_IWUSR,\n"
+ " \t\tmax_comp_streams_show, max_comp_streams_store);\n"
+ " static DEVICE_ATTR(comp_algorithm, S_IRUGO | S_IWUSR,\n"
+ "@@ -883,6 +917,7 @@ static struct attribute *zram_disk_attrs[] = {\n"
+ " \t&dev_attr_compr_data_size.attr,\n"
+ " \t&dev_attr_mem_used_total.attr,\n"
+ " \t&dev_attr_mem_used_max.attr,\n"
+ "+\t&dev_attr_mem_limit.attr,\n"
+ " \t&dev_attr_max_comp_streams.attr,\n"
+ " \t&dev_attr_comp_algorithm.attr,\n"
+ " \tNULL,\n"
+ "diff --git a/include/linux/zsmalloc.h b/include/linux/zsmalloc.h\n"
+ "index fb087ca06a88..41122251a2d0 100644\n"
+ "--- a/include/linux/zsmalloc.h\n"
+ "+++ b/include/linux/zsmalloc.h\n"
+ "@@ -49,4 +49,6 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle);\n"
+ " u64 zs_get_total_size_bytes(struct zs_pool *pool);\n"
+ " u64 zs_get_max_size_bytes(struct zs_pool *pool);\n"
+ " \n"
+ "+u64 zs_get_limit_size_bytes(struct zs_pool *pool);\n"
+ "+void zs_set_limit_size_bytes(struct zs_pool *pool, u64 limit);\n"
+ " #endif\n"
+ "diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c\n"
+ "index 3b5be076268a..8ca51118cf2b 100644\n"
+ "--- a/mm/zsmalloc.c\n"
+ "+++ b/mm/zsmalloc.c\n"
+ "@@ -220,6 +220,7 @@ struct zs_pool {\n"
+ " \tgfp_t flags;\t/* allocation flags used when growing pool */\n"
+ " \tunsigned long pages_allocated;\n"
+ " \tunsigned long max_pages_allocated;\n"
+ "+\tunsigned long pages_limited;\n"
+ " };\n"
+ " \n"
+ " /*\n"
+ "@@ -940,6 +941,11 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size)\n"
+ " \n"
+ " \tif (!first_page) {\n"
+ " \t\tspin_unlock(&class->lock);\n"
+ "+\n"
+ "+\t\tif (pool->pages_limited && (pool->pages_limited <\n"
+ "+\t\t\tpool->pages_allocated + class->pages_per_zspage))\n"
+ "+\t\t\treturn 0;\n"
+ "+\n"
+ " \t\tfirst_page = alloc_zspage(class, pool->flags);\n"
+ " \t\tif (unlikely(!first_page))\n"
+ " \t\t\treturn 0;\n"
+ "@@ -1132,6 +1138,24 @@ u64 zs_get_max_size_bytes(struct zs_pool *pool)\n"
+ " }\n"
+ " EXPORT_SYMBOL_GPL(zs_get_max_size_bytes);\n"
+ " \n"
+ "+void zs_set_limit_size_bytes(struct zs_pool *pool, u64 limit)\n"
+ "+{\n"
+ "+\tpool->pages_limited = round_down(limit, PAGE_SIZE) >> PAGE_SHIFT;\n"
+ "+}\n"
+ "+EXPORT_SYMBOL_GPL(zs_set_limit_size_bytes);\n"
+ "+\n"
+ "+u64 zs_get_limit_size_bytes(struct zs_pool *pool)\n"
+ "+{\n"
+ "+\tu64 npages;\n"
+ "+\n"
+ "+\tspin_lock(&pool->stat_lock);\n"
+ "+\tnpages = pool->pages_limited;\n"
+ "+\tspin_unlock(&pool->stat_lock);\n"
+ "+\treturn npages << PAGE_SHIFT;\n"
+ "+\n"
+ "+}\n"
+ "+EXPORT_SYMBOL_GPL(zs_get_limit_size_bytes);\n"
+ "+\n"
+ " module_init(zs_init);\n"
+ " module_exit(zs_exit);\n"
+ " \n"
+ "-- \n"
+ "2.0.0\n"
+ "\n"
+ "-- \n"
+ "Kind regards,\n"
+ Minchan Kim
 
-2639ad77a199b14cfe9127e9d3702d705807dda0387683392a71f5322d84bcdf
+d07d3bf65d0ee3016b2453264c97e8d134daf5682fe40694d8c57a4c5cec7893

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.