[PATCH 08/10] mm/ksm: use folio in try_to_merge_xx serie funcs

From: alexs
Date: Tue Jun 04 2024 - 00:23:21 EST


From: "Alex Shi (tencent)" <alexs@xxxxxxxxxx>

The try_to_merge_ serie funcs are using folios, so change the parameter
and variable 'page' to folio to save compound checks.

Signed-off-by: Alex Shi (tencent) <alexs@xxxxxxxxxx>
---
mm/ksm.c | 54 ++++++++++++++++++++++++------------------------------
1 file changed, 24 insertions(+), 30 deletions(-)

diff --git a/mm/ksm.c b/mm/ksm.c
index 14a7ca53fc91..b9c04ce677b9 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1540,22 +1540,18 @@ static int try_to_merge_one_page(struct vm_area_struct *vma, struct folio *folio
* This function returns 0 if the pages were merged, -EFAULT otherwise.
*/
static int try_to_merge_with_ksm_page(struct ksm_rmap_item *rmap_item,
- struct page *page, struct page *kpage)
+ struct folio *folio, struct folio *kfolio)
{
struct mm_struct *mm = rmap_item->mm;
struct vm_area_struct *vma;
int err = -EFAULT;
- struct folio *kfolio;

mmap_read_lock(mm);
vma = find_mergeable_vma(mm, rmap_item->address);
if (!vma)
goto out;

- if (kpage)
- kfolio = page_folio(kpage);
-
- err = try_to_merge_one_page(vma, page_folio(page), rmap_item, kfolio);
+ err = try_to_merge_one_page(vma, folio, rmap_item, kfolio);
if (err)
goto out;

@@ -1567,8 +1563,8 @@ static int try_to_merge_with_ksm_page(struct ksm_rmap_item *rmap_item,
get_anon_vma(vma->anon_vma);
out:
mmap_read_unlock(mm);
- trace_ksm_merge_with_ksm_page(kpage, page_to_pfn(kpage ? kpage : page),
- rmap_item, mm, err);
+ trace_ksm_merge_with_ksm_page(kfolio, folio_pfn(kfolio ? kfolio : folio),
+ rmap_item, mm, err);
return err;
}

@@ -1582,17 +1578,17 @@ static int try_to_merge_with_ksm_page(struct ksm_rmap_item *rmap_item,
* Note that this function upgrades page to ksm page: if one of the pages
* is already a ksm page, try_to_merge_with_ksm_page should be used.
*/
-static struct page *try_to_merge_two_pages(struct ksm_rmap_item *rmap_item,
- struct page *page,
+static struct folio *try_to_merge_two_pages(struct ksm_rmap_item *rmap_item,
+ struct folio *folio,
struct ksm_rmap_item *tree_rmap_item,
- struct page *tree_page)
+ struct folio *tree_folio)
{
int err;

- err = try_to_merge_with_ksm_page(rmap_item, page, NULL);
+ err = try_to_merge_with_ksm_page(rmap_item, folio, NULL);
if (!err) {
err = try_to_merge_with_ksm_page(tree_rmap_item,
- tree_page, page);
+ tree_folio, folio);
/*
* If that fails, we have a ksm page with only one pte
* pointing to it: so break it.
@@ -1600,7 +1596,7 @@ static struct page *try_to_merge_two_pages(struct ksm_rmap_item *rmap_item,
if (err)
break_cow(rmap_item);
}
- return err ? NULL : page;
+ return err ? NULL : folio;
}

static __always_inline
@@ -2310,14 +2306,13 @@ static void cmp_and_merge_page(struct page *page, struct ksm_rmap_item *rmap_ite
{
struct mm_struct *mm = rmap_item->mm;
struct ksm_rmap_item *tree_rmap_item;
- struct page *tree_page = NULL;
struct folio *tree_folio = NULL;
struct ksm_stable_node *stable_node;
- struct page *kpage;
+ struct folio *kfolio;
unsigned int checksum;
int err;
bool max_page_sharing_bypass = false;
- struct folio *folio, *kfolio;
+ struct folio *folio;

folio = page_folio(page);
stable_node = folio_stable_node(folio);
@@ -2353,7 +2348,7 @@ static void cmp_and_merge_page(struct page *page, struct ksm_rmap_item *rmap_ite
if (kfolio == ERR_PTR(-EBUSY))
return;

- err = try_to_merge_with_ksm_page(rmap_item, page, folio_page(kfolio, 0));
+ err = try_to_merge_with_ksm_page(rmap_item, folio, kfolio);
if (!err) {
/*
* The page was successfully merged:
@@ -2415,8 +2410,8 @@ static void cmp_and_merge_page(struct page *page, struct ksm_rmap_item *rmap_ite
if (tree_rmap_item) {
bool split;

- kpage = try_to_merge_two_pages(rmap_item, page,
- tree_rmap_item, tree_page);
+ kfolio = try_to_merge_two_pages(rmap_item, folio,
+ tree_rmap_item, tree_folio);
/*
* If both pages we tried to merge belong to the same compound
* page, then we actually ended up increasing the reference
@@ -2427,23 +2422,22 @@ static void cmp_and_merge_page(struct page *page, struct ksm_rmap_item *rmap_ite
* afterwards, the reference count will be correct and
* split_huge_page should succeed.
*/
- split = PageTransCompound(page)
- && compound_head(page) == compound_head(tree_page);
- put_page(tree_page);
- if (kpage) {
+ split = folio_test_large(folio) && folio == kfolio;
+ folio_put(tree_folio);
+ if (kfolio) {
/*
* The pages were successfully merged: insert new
* node in the stable tree and add both rmap_items.
*/
- lock_page(kpage);
- stable_node = stable_tree_insert(page_folio(kpage));
+ folio_lock(kfolio);
+ stable_node = stable_tree_insert(kfolio);
if (stable_node) {
stable_tree_append(tree_rmap_item, stable_node,
false);
stable_tree_append(rmap_item, stable_node,
false);
}
- unlock_page(kpage);
+ folio_unlock(kfolio);

/*
* If we fail to insert the page into the stable tree,
@@ -2465,10 +2459,10 @@ static void cmp_and_merge_page(struct page *page, struct ksm_rmap_item *rmap_ite
* the page is locked, it is better to skip it and
* perhaps try again later.
*/
- if (!trylock_page(page))
+ if (!folio_trylock(folio))
return;
- split_huge_page(page);
- unlock_page(page);
+ split_folio(folio);
+ folio_unlock(folio);
}
}
}
--
2.43.0