[Devel] [PATCH RHEL7 COMMIT] tswap: do not populate on global reclaim
Konstantin Khorenko
khorenko at virtuozzo.com
Fri Jul 17 06:52:55 PDT 2015
The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.25
------>
commit baf219c281e0f275ff996effd9a8a2043e06ec3e
Author: Vladimir Davydov <vdavydov at parallels.com>
Date: Fri Jul 17 17:52:55 2015 +0400
tswap: do not populate on global reclaim
Tswap was introduced for storing swap cache pages that do not fit in
container RAM limit in order to avoid costly swap out when there is
enough free memory on the host. Therefore there is no point in moving
swap cache pages to tswap on global memory shortage. Moreover, it is
dangerous, because on tswap reclaim we do not actually free pages, but
move them back to swap cache in the hope that they will be written back
and freed soon. However, there is a chance that they won't, instead they
can be moved back to tswap again. As a result of such a page ping-pong,
the system may become unresponsive.
This patch therefore makes tswap only adopt swap cache pages on local
reclaim (PF_MEMALLOC is unset on current). Since after this change it is
valid to trigger global reclaim from inside tswap_frontswap_store, this
patch also makes tswap_frontswap_store use GFP_NOIO instead of
GFP_NOWAIT and issue radix tree preallocation before inserting a page to
tswap_page_tree.
https://jira.sw.ru/browse/PSBM-34876
Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
Reviewed-by: Kirill Tkhai <ktkhai at odin.com>
---
mm/tswap.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/mm/tswap.c b/mm/tswap.c
index cdaa98a..dc1253f 100644
--- a/mm/tswap.c
+++ b/mm/tswap.c
@@ -14,6 +14,8 @@
#include <linux/shrinker.h>
#include <linux/frontswap.h>
+#define TSWAP_GFP_MASK (GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN)
+
static RADIX_TREE(tswap_page_tree, GFP_ATOMIC | __GFP_NOWARN);
static DEFINE_SPINLOCK(tswap_lock);
@@ -67,6 +69,10 @@ static int tswap_insert_page(swp_entry_t entry, struct page *page)
{
int err;
+ err = radix_tree_preload(TSWAP_GFP_MASK);
+ if (err)
+ return err;
+
set_page_private(page, entry.val);
spin_lock(&tswap_lock);
err = radix_tree_insert(&tswap_page_tree, entry.val, page);
@@ -75,6 +81,8 @@ static int tswap_insert_page(swp_entry_t entry, struct page *page)
tswap_nr_pages++;
}
spin_unlock(&tswap_lock);
+
+ radix_tree_preload_end();
return err;
}
@@ -268,8 +276,10 @@ static int tswap_frontswap_store(unsigned type, pgoff_t offset,
if (cache_page)
goto copy;
- cache_page = alloc_page(__GFP_HIGHMEM | __GFP_NORETRY |
- __GFP_NOMEMALLOC | __GFP_NOWARN);
+ if (current->flags & PF_MEMALLOC)
+ return -1;
+
+ cache_page = alloc_page(TSWAP_GFP_MASK | __GFP_HIGHMEM);
if (!cache_page)
return -1;
More information about the Devel
mailing list