From: Minchan Kim <minchan@kernel.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org,
Hugh Dickins <hughd@google.com>, Shaohua Li <shli@kernel.org>,
Jerome Marchand <jmarchan@redhat.com>,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
Dan Streetman <ddstreet@ieee.org>,
Nitin Gupta <ngupta@vflare.org>,
Luigi Semenzato <semenzato@google.com>,
juno.choi@lge.com, Minchan Kim <minchan@kernel.org>
Subject: [PATCH v1 4/5] zram: add swap full hint
Date: Mon, 22 Sep 2014 09:03:10 +0900 [thread overview]
Message-ID: <1411344191-2842-5-git-send-email-minchan@kernel.org> (raw)
In-Reply-To: <1411344191-2842-1-git-send-email-minchan@kernel.org>
This patch implement SWAP_FULL handler in zram so that VM can
know whether zram is full or not and use it to stop anonymous
page reclaim.
How to judge fullness is below,
fullness = (100 * used space / total space)
It means the higher fullness is, the slower we reach zram full.
Now, default of fullness is 80 so that it biased more momory
consumption rather than early OOM kill.
Above logic works only when used space of zram hit over the limit
but zram also pretend to be full once 32 consecutive allocation
fail happens. It's safe guard to prevent system hang caused by
fragment uncertainty.
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
drivers/block/zram/zram_drv.c | 60 ++++++++++++++++++++++++++++++++++++++++---
drivers/block/zram/zram_drv.h | 1 +
2 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 22a37764c409..649cad9d0b1c 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -43,6 +43,20 @@ static const char *default_compressor = "lzo";
/* Module params (documentation at end) */
static unsigned int num_devices = 1;
+/*
+ * If (100 * used_pages / total_pages) >= ZRAM_FULLNESS_PERCENT),
+ * we regards it as zram-full. It means that the higher
+ * ZRAM_FULLNESS_PERCENT is, the slower we reach zram full.
+ */
+#define ZRAM_FULLNESS_PERCENT 80
+
+/*
+ * If zram fails to allocate memory consecutively up to this,
+ * we regard it as zram-full. It's safe guard to prevent too
+ * many swap write fail due to lack of fragmentation uncertainty.
+ */
+#define ALLOC_FAIL_MAX 32
+
#define ZRAM_ATTR_RO(name) \
static ssize_t zram_attr_##name##_show(struct device *d, \
struct device_attribute *attr, char *b) \
@@ -148,6 +162,7 @@ static ssize_t mem_limit_store(struct device *dev,
down_write(&zram->init_lock);
zram->limit_pages = PAGE_ALIGN(limit) >> PAGE_SHIFT;
+ atomic_set(&zram->alloc_fail, 0);
up_write(&zram->init_lock);
return len;
@@ -410,6 +425,7 @@ static void zram_free_page(struct zram *zram, size_t index)
atomic64_sub(zram_get_obj_size(meta, index),
&zram->stats.compr_data_size);
atomic64_dec(&zram->stats.pages_stored);
+ atomic_set(&zram->alloc_fail, 0);
meta->table[index].handle = 0;
zram_set_obj_size(meta, index, 0);
@@ -597,10 +613,15 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
}
alloced_pages = zs_get_total_pages(meta->mem_pool);
- if (zram->limit_pages && alloced_pages > zram->limit_pages) {
- zs_free(meta->mem_pool, handle);
- ret = -ENOMEM;
- goto out;
+ if (zram->limit_pages) {
+ if (alloced_pages > zram->limit_pages) {
+ zs_free(meta->mem_pool, handle);
+ atomic_inc(&zram->alloc_fail);
+ ret = -ENOMEM;
+ goto out;
+ } else {
+ atomic_set(&zram->alloc_fail, 0);
+ }
}
update_used_max(zram, alloced_pages);
@@ -711,6 +732,7 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
down_write(&zram->init_lock);
zram->limit_pages = 0;
+ atomic_set(&zram->alloc_fail, 0);
if (!init_done(zram)) {
up_write(&zram->init_lock);
@@ -944,6 +966,34 @@ static int zram_slot_free_notify(struct block_device *bdev,
return 0;
}
+static int zram_full(struct block_device *bdev, void *arg)
+{
+ struct zram *zram;
+ struct zram_meta *meta;
+ unsigned long total_pages, compr_pages;
+
+ zram = bdev->bd_disk->private_data;
+ if (!zram->limit_pages)
+ return 0;
+
+ meta = zram->meta;
+ total_pages = zs_get_total_pages(meta->mem_pool);
+
+ if (total_pages >= zram->limit_pages) {
+
+ compr_pages = atomic64_read(&zram->stats.compr_data_size)
+ >> PAGE_SHIFT;
+ if ((100 * compr_pages / total_pages)
+ >= ZRAM_FULLNESS_PERCENT)
+ return 1;
+ }
+
+ if (atomic_read(&zram->alloc_fail) > ALLOC_FAIL_MAX)
+ return 1;
+
+ return 0;
+}
+
static int zram_swap_hint(struct block_device *bdev,
unsigned int hint, void *arg)
{
@@ -951,6 +1001,8 @@ static int zram_swap_hint(struct block_device *bdev,
if (hint == SWAP_FREE)
ret = zram_slot_free_notify(bdev, (unsigned long)arg);
+ else if (hint == SWAP_FULL)
+ ret = zram_full(bdev, arg);
return ret;
}
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index c6ee271317f5..fcf3176a9f15 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -113,6 +113,7 @@ struct zram {
u64 disksize; /* bytes */
int max_comp_streams;
struct zram_stats stats;
+ atomic_t alloc_fail;
/*
* the number of pages zram can consume for storing compressed data
*/
--
2.0.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2014-09-22 0:02 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-22 0:03 [PATCH v1 0/5] stop anon reclaim when zram is full Minchan Kim
2014-09-22 0:03 ` [PATCH v1 1/5] zram: generalize swap_slot_free_notify Minchan Kim
2014-09-22 20:41 ` Andrew Morton
2014-09-23 4:45 ` Minchan Kim
2014-09-22 0:03 ` [PATCH v1 2/5] mm: add full variable in swap_info_struct Minchan Kim
2014-09-22 20:45 ` Andrew Morton
2014-09-23 4:45 ` Minchan Kim
2014-09-24 2:53 ` Dan Streetman
2014-09-24 7:57 ` Minchan Kim
2014-09-22 0:03 ` [PATCH v1 3/5] mm: VM can be aware of zram fullness Minchan Kim
2014-09-24 14:12 ` Dan Streetman
2014-09-25 1:06 ` Minchan Kim
2014-09-25 1:31 ` Dan Streetman
2014-09-22 0:03 ` Minchan Kim [this message]
2014-09-22 21:11 ` [PATCH v1 4/5] zram: add swap full hint Andrew Morton
2014-09-23 4:56 ` Minchan Kim
2014-09-23 21:17 ` Andrew Morton
2014-09-24 7:57 ` Minchan Kim
2014-09-24 15:10 ` Jerome Marchand
2014-09-25 1:07 ` Minchan Kim
2014-09-24 14:01 ` Dan Streetman
2014-09-25 1:02 ` Minchan Kim
2014-09-25 15:52 ` Dan Streetman
2014-10-06 23:36 ` Minchan Kim
2014-10-06 23:46 ` Minchan Kim
2014-10-08 18:29 ` Dan Streetman
2014-09-22 0:03 ` [PATCH v1 5/5] zram: add fullness knob to control swap full Minchan Kim
2014-09-22 21:17 ` Andrew Morton
2014-09-23 4:57 ` Minchan Kim
2014-12-02 3:04 ` [PATCH v1 0/5] stop anon reclaim when zram is full Minchan Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1411344191-2842-5-git-send-email-minchan@kernel.org \
--to=minchan@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=ddstreet@ieee.org \
--cc=hughd@google.com \
--cc=jmarchan@redhat.com \
--cc=juno.choi@lge.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ngupta@vflare.org \
--cc=semenzato@google.com \
--cc=sergey.senozhatsky@gmail.com \
--cc=shli@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).