[Devel] [PATCH rh7 1/2] mm/tcache: drop useless replace logic during attach page.

Andrey Ryabinin aryabinin at virtuozzo.com
Wed Jul 19 18:32:29 MSK 2017


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 94f03832804..3778523bbce 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;
 }
-- 
2.13.0



More information about the Devel mailing list