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

Submitted by Andrey Ryabinin on July 19, 2017, 3:32 p.m.

Details

Message ID 20170719153230.8042-1-aryabinin@virtuozzo.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Andrey Ryabinin July 19, 2017, 3:32 p.m.
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@virtuozzo.com>
---
 mm/tcache.c | 44 +++++++++++++-------------------------------
 1 file changed, 13 insertions(+), 31 deletions(-)

Patch hide | download patch | download mbox

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;
 }