diff mbox series

[1/2] mm/ksm: re-search unstable tree when tree_rmap_item is stale

Message ID 20240508-b4-ksm-unstable-insert-v1-1-631cdbc2b77f@linux.dev (mailing list archive)
State New
Headers show
Series mm/ksm: optimize unstable_tree_search_insert() | expand

Commit Message

Chengming Zhou May 8, 2024, 11:35 a.m. UTC
From: Chengming Zhou <zhouchengming@bytedance.com>

Now unstable_tree_search_insert() will return NULL if encounter a stale
tree_rmap_item, in which case get_mergeable_page() return NULL.

More reasonable handling is to remove stale rmap_item out of unstable
tree and re-search from root. That stale rmap_item will be reclaimed
when next time of scan.

So we can insert our rmap_item successfully instead of returning NULL.

Signed-off-by: Chengming Zhou <zhouchengming@bytedance.com>
---
 mm/ksm.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/mm/ksm.c b/mm/ksm.c
index e1034bf1c937..66219983eb3a 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -2196,12 +2196,14 @@  struct ksm_rmap_item *unstable_tree_search_insert(struct ksm_rmap_item *rmap_ite
 {
 	struct rb_node **new;
 	struct rb_root *root;
-	struct rb_node *parent = NULL;
+	struct rb_node *parent;
 	int nid;
 
 	nid = get_kpfn_nid(page_to_pfn(page));
 	root = root_unstable_tree + nid;
+again:
 	new = &root->rb_node;
+	parent = NULL;
 
 	while (*new) {
 		struct ksm_rmap_item *tree_rmap_item;
@@ -2211,8 +2213,10 @@  struct ksm_rmap_item *unstable_tree_search_insert(struct ksm_rmap_item *rmap_ite
 		cond_resched();
 		tree_rmap_item = rb_entry(*new, struct ksm_rmap_item, node);
 		tree_page = get_mergeable_page(tree_rmap_item);
-		if (!tree_page)
-			return NULL;
+		if (!tree_page) {
+			remove_rmap_item_from_tree(tree_rmap_item);
+			goto again;
+		}
 
 		/*
 		 * Don't substitute a ksm page for a forked page.