[Devel] [PATCH RHEL7 COMMIT] mm/tcache: drop useless replace logic during attach page.

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jul 20 11:52:42 MSK 2017


The commit is pushed to "branch-rh7-3.10.0-514.26.1.vz7.33.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.26.1.vz7.33.11
------>
commit 3858830c76c912e9bf9253da045d108f3a537cb4
Author: Andrey Ryabinin <aryabinin at virtuozzo.com>
Date:   Thu Jul 20 12:52:42 2017 +0400

    mm/tcache: drop useless replace logic during attach page.
    
    tcache_attach_page() written with the assumption that the slot
    in the page_tree may be already occupied by other page, so it replaces
    such page. However, such situations should never be possible at all.
    Before putting any page to the tcache we supposed to either get
    this page from tcache or invalidate it. So when we put the page,
    slot in tcache page_tree should be already empty.
    
    Just in case add WARN_ON(err == -EXISTS) to catch such not supposed
    to happen situations.
    
    https://jira.sw.ru/browse/PSBM-64727
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 mm/tcache.c | 44 +++++++++++++-------------------------------
 1 file changed, 13 insertions(+), 31 deletions(-)

diff --git a/mm/tcache.c b/mm/tcache.c
index 94f0383..3778523 100644
--- a/mm/tcache.c
+++ b/mm/tcache.c
@@ -716,14 +716,11 @@ static inline void tcache_put_page(struct page *page)
 	}
 }
 
-static int tcache_page_tree_replace(struct tcache_node *node, pgoff_t index,
-				    struct page *page, struct page **old_page)
+static int tcache_page_tree_insert(struct tcache_node *node, pgoff_t index,
+				    struct page *page)
 {
-	void **pslot;
 	int err = 0;
 
-	*old_page = NULL;
-
 	/*
 	 * If the node was invalidated after we looked it up, abort in order to
 	 * avoid clashes with tcache_invalidate_node_pages.
@@ -733,22 +730,13 @@ static int tcache_page_tree_replace(struct tcache_node *node, pgoff_t index,
 		goto out;
 	}
 
-	pslot = radix_tree_lookup_slot(&node->page_tree, index);
-	if (pslot) {
-		*old_page = radix_tree_deref_slot_protected(pslot,
-							    &node->tree_lock);
-		radix_tree_replace_slot(pslot, page);
-		__dec_zone_page_state(*old_page, NR_FILE_PAGES);
+	err = radix_tree_insert(&node->page_tree, index, page);
+	WARN_ON(err == -EEXIST);
+	if (!err) {
+		if (!node->nr_pages++)
+			tcache_hold_node(node);
+		__this_cpu_inc(nr_tcache_pages);
 		__inc_zone_page_state(page, NR_FILE_PAGES);
-	} else {
-		err = radix_tree_insert(&node->page_tree, index, page);
-		BUG_ON(err == -EEXIST);
-		if (!err) {
-			if (!node->nr_pages++)
-				tcache_hold_node(node);
-			__this_cpu_inc(nr_tcache_pages);
-			__inc_zone_page_state(page, NR_FILE_PAGES);
-		}
 	}
 out:
 	return err;
@@ -784,24 +772,18 @@ static struct page *tcache_page_tree_delete(struct tcache_node *node,
 static noinline_for_stack int
 tcache_attach_page(struct tcache_node *node, pgoff_t index, struct page *page)
 {
-	struct page *old_page;
 	unsigned long flags;
 	int err = 0;
 
 	tcache_init_page(page, node, index);
 
 	spin_lock_irqsave(&node->tree_lock, flags);
-	err = tcache_page_tree_replace(node, index, page, &old_page);
-	if (err)
-		goto out;
-
-	if (old_page) {
-		tcache_lru_del(node->pool, old_page, false);
-		tcache_put_page(old_page);
+	err = tcache_page_tree_insert(node, index, page);
+	if (!err) {
+		tcache_hold_page(page);
+		tcache_lru_add(node->pool, page);
 	}
-	tcache_hold_page(page);
-	tcache_lru_add(node->pool, page);
-out:
+
 	spin_unlock_irqrestore(&node->tree_lock, flags);
 	return err;
 }


More information about the Devel mailing list