Re: [PATCH] mm: huge_memory: convert split_huge_pages_all() to use a folio

From: Kefeng Wang
Date: Thu Dec 29 2022 - 20:36:37 EST




On 2022/12/30 7:28, Andrew Morton wrote:
On Thu, 29 Dec 2022 20:25:03 +0800 Kefeng Wang <wangkefeng.wang@xxxxxxxxxx> wrote:

Straightforwardly convert split_huge_pages_all() to use a folio.

Signed-off-by: Kefeng Wang <wangkefeng.wang@xxxxxxxxxx>
---
mm/huge_memory.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 266c4b557946..c8cbe7f62eaa 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2932,6 +2932,7 @@ static void split_huge_pages_all(void)
{
struct zone *zone;
struct page *page;
+ struct folio *folio;
unsigned long pfn, max_zone_pfn;
unsigned long total = 0, split = 0;
@@ -2944,24 +2945,32 @@ static void split_huge_pages_all(void)
int nr_pages;
page = pfn_to_online_page(pfn);
- if (!page || !get_page_unless_zero(page))
+ if (!page || PageTail(page))
+ continue;

Why is the PageTail() test added?
This function is trying to split huge pages, it traverse all the pfn, the huge page already split when we met Head page, most importantly, get_page_unless_zero() will do nothing on Tail page too.

+ folio = page_folio(page);
+ if (!folio_try_get(folio))
continue;
- if (zone != page_zone(page))
+ if (unlikely(page_folio(page) != folio))

And this?

I think this is a double check in case of page is already changed by someone else, suggested by Matthew[1]

[1] https://lore.kernel.org/linux-mm/20221227195004.2809-1-sj@xxxxxxxxxx/T/#m33047c152f6793bfebaa55cb1f4662fed73508d2