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.