[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