kselftest: mm: fix some failure of split_huge_page_test
Subsystems (4)
v4 cover kselftest: mm: fix some failure of split_huge_page_test
split_huge_page_test can fail for the following reasons:
1. During the test, khugepaged may collapse previously split pages again, causing intermittent failures.
2. Since glibc commit 321e1fc73f (“malloc: Enable 2MB THP by default on AArch64”), glibc may call madvise(MADV_HUGEPAGE) for sufficiently large allocations made by memalign(). The underlying VMA may start at a different address from the aligned address returned by memalign(). Moreover, a subsequent madvise(MADV_HUGEPAGE) call does not split the VMA because it already has the same advice.
This causes the test to fail because the check_huge_xxx() helpers incorrectly require the address returned by memalign() to match the VMA start address reported in /proc/self/smaps.
Address these issues by applying MADV_NOHUGEPAGE after faulting in the huge page, preventing khugepaged from collapsing it again, and instead of relying on /proc/self/smaps, use /proc/self/pagemap and /proc/kpageflags to detect huge-page mappings and large folios:
1. If hpage_size == pmd_pagesize, check PAGE_IS_HUGE instead of using check_large_folios(), since only the mapping type matters. This identifies PMD-mapped huge pages.
2. Otherwise, use check_large_folios() to detect large folios. This covers mTHP cases.
3. Check the folio flags according to the type of huge page.
Also, current usage of memalign() would result memory area may unexpectedly merge with an adjacent VMA, causing tests that inspect it through /proc/self/smaps to fail.
Eliminate this potential source of test flakiness by introducing alloc_isolated_mem(), which places guard regions before and after the allocated area to prevent unexpected VMA merging.
This patch based on mm-unstable
---
Changes in v4:
- reparse commit message.
- introduce alloc_isolated_mem().
- make madv_nohuge() helper according to suggestion.
- Link to v3: https://lore.kernel.org/r/[email protected]
Changes in v3:
- change message in case of failure of madvise() with MADV_NOHUGEPAGE.
- fix collapse_single_mthp (mthp_khugepaged:anon) test case failure.
- Link to v2: https://lore.kernel.org/all/[email protected]/
Changes in v2:
- rebase to mm-unstable.
- add message in case of failure of madvise() with MADV_NOHUGEPAGE.
- fix wrong setup expected_huge in check_huge_shmem().
- Link to v1: https://lore.kernel.org/r/[email protected]
---
Yeoreum Yun (3):
kselftest: mm: prevent random failure of huge page split for khugepaged
kselftest: mm: replace usage of /proc/self/smaps for check_huge_xxx() helper
kselftest: mm: introduce alloc_isolated_mem()
tools/testing/selftests/mm/pagemap_ioctl.c | 18 +- tools/testing/selftests/mm/soft-dirty.c | 6 +- tools/testing/selftests/mm/split_huge_page_test.c | 27 ++- tools/testing/selftests/mm/vm_util.c | 212 ++++++++++++++++------ tools/testing/selftests/mm/vm_util.h | 3 + 5 files changed, 192 insertions(+), 74 deletions(-)
---
base-commit: e3b5239afe1b8f0194db7436b17c33e94c1988c4
change-id: 20260820-fix_split-f44939ec44b8
Best regards,
Signature · 2 lines
Sincerely, Yeoreum Yun
PATCH v4 1/3 kselftest: mm: prevent random failure of huge page split for khugepaged
There're some random failure for split_huge_page_test when khugepaged collapses pages into pmd again which had split by the test.
Prevent the khugepaged's collapses for split page by setting the mapped pmd-huge-page with MADV_NOHUGEPAGE before split.
--- tools/testing/selftests/mm/split_huge_page_test.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
tools/testing/selftests/mm/split_huge_page_test.c +19 -0
@@ -168,6 +168,14 @@ static char *allocate_zero_filled_hugepage(size_t len)return result; } +static void madv_nohuge (void *addr,size_t len) +{ +if (!madvise (addr, len,MADV_NOHUGEPAGE )) +return ; + +ksft_exit_fail_msg ("MADV_NOHUGEPAGE failed, err=%d\n" , errno); +} +static void verify_rss_anon_split_huge_page_all_zeroes (char *one_page,int nr_hpages,size_t len) {unsigned long rss_anon_before, rss_anon_after;
@@ -180,6 +188,9 @@ static void verify_rss_anon_split_huge_page_all_zeroes(char *one_page, int nr_hpif (!rss_anon_before)ksft_exit_fail_msg ("No RssAnon is allocated before split\n" ); +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (one_page, len); +/* split all THPs */ write_debugfs (PID_FMT ,getpid (), (uint64_t )one_page, (uint64_t )one_page + len,0 );
@@ -227,6 +238,9 @@ static void split_pmd_thp_to_order(int order)if (!check_huge_anon (one_page,4 * pmd_pagesize,4 , pmd_pagesize))ksft_exit_fail_msg ("No THP is allocated\n" ); +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (one_page, len); +/* split all THPs */ write_debugfs (PID_FMT ,getpid (), (uint64_t )one_page, (uint64_t )one_page + len, order);
@@ -275,6 +289,9 @@ static void split_pte_mapped_thp(void) goto out; } +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (thp_area, thp_area_size); +/* * To challenge spitting code, we will mremap a single page of each * THP (page[i] of thp[i]) in the thp_area into page_area. This will
@@ -542,6 +559,8 @@ static int create_pagecache_thp_and_fd(const char *testfile, size_t fd_size,ksft_test_result_skip ("Pagecache folio split skipped\n" );return -2 ; } +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (*addr, fd_size);return 0 ; err_out_close:close (*fd);
Signature · 1 line
2.43.0
Re: [PATCH v4 1/3] kselftest: mm: prevent random failure of huge page split for khugepaged
Quoted 6 lines · Yeoreum Yun
There're some random failure for
split_huge_page_testwhen khugepaged collapses pages into pmd again which had split by the test.Prevent the khugepaged's collapses for split page by setting the mapped pmd-huge-page with
MADV_NOHUGEPAGEbefore split.
Quoted 7 lines
Suggested-by Kevin Brodsky <[email protected]>Suggested-by Lorenzo Stoakes (ARM) <[email protected]>Signed-off-by Yeoreum Yun <[email protected]>--- tools/testing/selftests/mm/split_huge_page_test.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
LGTM.
Signature · 2 lines
Best Regards, Yan, Zi
Re: [PATCH v4 1/3] kselftest: mm: prevent random failure of huge page split for khugepaged
In reply to Yeoreum YunQuoted 5 lines · Yeoreum Yun
There're some random failure for
split_huge_page_testwhen khugepaged collapses pages into pmd again which had split by the test.Prevent the khugepaged's collapses for split page by setting the mapped pmd-huge-page with
MADV_NOHUGEPAGEbefore split.
Maybe worth saying that MADV_NOHUGEPAGE doesn't immediately split anything, just prevents future khugepaged collapses?
Quoted 4 lines
Suggested-by Kevin Brodsky <[email protected]>Suggested-by Lorenzo Stoakes (ARM) <[email protected]>Signed-off-by Yeoreum Yun <[email protected]>
LGTM, thanks, with a few nits above/below (sorry! :P)
tools/testing/selftests/mm/split_huge_page_test.c static char *allocate_zero_filled_hugepage(size_t len) · line 171
Quoted 13 lines
--- tools/testing/selftests/mm/split_huge_page_test.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)tools/testing/selftests/mm/split_huge_page_test.c +1
-0@@ -168,6 +168,14 @@ static char *allocate_zero_filled_hugepage(size_t len)return result; } +static void madv_nohuge (void *addr,size_t len)
Maybe call it disable_khugepaged() to make it explicit that's what this is doing rather than eliminating any THP pages in the range?
tools/testing/selftests/mm/split_huge_page_test.c static char *allocate_zero_filled_hugepage(size_t len) · line 172
Quoted 1 line
tools/testing/selftests/mm/split_huge_page_test.c +1
-0+{
Maybe a comment here like:
/* * Disables khugepaged from collapsing THPs in range, existing THP * pages remain. */
Quoted 50 lines
tools/testing/selftests/mm/split_huge_page_test.c +17
-1+if (!madvise (addr, len,MADV_NOHUGEPAGE )) +return ; + +ksft_exit_fail_msg ("MADV_NOHUGEPAGE failed, err=%d\n" , errno); +} +static void verify_rss_anon_split_huge_page_all_zeroes (char *one_page,int nr_hpages,size_t len) {unsigned long rss_anon_before, rss_anon_after;@@ -180,6 +188,9 @@ static void verify_rss_anon_split_huge_page_all_zeroes(char *one_page, int nr_hpif (!rss_anon_before)ksft_exit_fail_msg ("No RssAnon is allocated before split\n" ); +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (one_page, len); +/* split all THPs */ write_debugfs (PID_FMT ,getpid (), (uint64_t )one_page, (uint64_t )one_page + len,0 );@@ -227,6 +238,9 @@ static void split_pmd_thp_to_order(int order)if (!check_huge_anon (one_page,4 * pmd_pagesize,4 , pmd_pagesize))ksft_exit_fail_msg ("No THP is allocated\n" ); +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (one_page, len); +/* split all THPs */ write_debugfs (PID_FMT ,getpid (), (uint64_t )one_page, (uint64_t )one_page + len, order);@@ -275,6 +289,9 @@ static void split_pte_mapped_thp(void) goto out; } +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (thp_area, thp_area_size); +/* * To challenge spitting code, we will mremap a single page of each * THP (page[i] of thp[i]) in the thp_area into page_area. This will @@ -542,6 +559,8 @@ static int create_pagecache_thp_and_fd(const char *testfile, size_t fd_size,ksft_test_result_skip ("Pagecache folio split skipped\n" );return -2 ; } +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (*addr, fd_size);return 0 ; err_out_close:close (*fd); --
Quoted 2 lines
2.43.0
--
Cheers, Lorenzo
Lorenzo Stoakes (ARM)
reviewerRe: [PATCH v4 1/3] kselftest: mm: prevent random failure of huge page split for khugepaged
Quoted 12 lines · Lorenzo Stoakes (ARM)
Maybe call it
disable_khugepaged()to make it explicit that's what this is doing rather than eliminating any THP pages in the range?Quoted 1 line
+{
Maybe a comment here like:
/* * Disables khugepaged from collapsing THPs in range, existing THP * pages remain. */
Oh and with these changes you can delete all of the:
/* Prevent khugepaged from collapsing the pages. */
Comments below as they will be implied by the name and explained by the comment :)
Thanks!
Quoted 49 lines
Quoted 49 lines
tools/testing/selftests/mm/split_huge_page_test.c +17
-0+if (!madvise (addr, len,MADV_NOHUGEPAGE )) +return ; + +ksft_exit_fail_msg ("MADV_NOHUGEPAGE failed, err=%d\n" , errno); +} +static void verify_rss_anon_split_huge_page_all_zeroes (char *one_page,int nr_hpages,size_t len) {unsigned long rss_anon_before, rss_anon_after;@@ -180,6 +188,9 @@ static void verify_rss_anon_split_huge_page_all_zeroes(char *one_page, int nr_hpif (!rss_anon_before)ksft_exit_fail_msg ("No RssAnon is allocated before split\n" ); +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (one_page, len); +/* split all THPs */ write_debugfs (PID_FMT ,getpid (), (uint64_t )one_page, (uint64_t )one_page + len,0 );@@ -227,6 +238,9 @@ static void split_pmd_thp_to_order(int order)if (!check_huge_anon (one_page,4 * pmd_pagesize,4 , pmd_pagesize))ksft_exit_fail_msg ("No THP is allocated\n" ); +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (one_page, len); +/* split all THPs */ write_debugfs (PID_FMT ,getpid (), (uint64_t )one_page, (uint64_t )one_page + len, order);@@ -275,6 +289,9 @@ static void split_pte_mapped_thp(void) goto out; } +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (thp_area, thp_area_size); +/* * To challenge spitting code, we will mremap a single page of each * THP (page[i] of thp[i]) in the thp_area into page_area. This will @@ -542,6 +559,8 @@ static int create_pagecache_thp_and_fd(const char *testfile, size_t fd_size,ksft_test_result_skip ("Pagecache folio split skipped\n" );return -2 ; } +/* Prevent khugepaged from collapsing the pages. */ +madv_nohuge (*addr, fd_size);return 0 ; err_out_close:close (*fd);
Quoted 6 lines
Quoted 3 lines
--
2.43.0--
Cheers, Lorenzo
--
Cheers, Lorenzo
Re: [PATCH v4 1/3] kselftest: mm: prevent random failure of huge page split for khugepaged
In reply to Lorenzo Stoakes (ARM)Quoted 36 lines · Lorenzo Stoakes (ARM)
Quoted 5 lines · Yeoreum Yun
There're some random failure for
split_huge_page_testwhen khugepaged collapses pages into pmd again which had split by the test.Prevent the khugepaged's collapses for split page by setting the mapped pmd-huge-page with
MADV_NOHUGEPAGEbefore split.Maybe worth saying that
MADV_NOHUGEPAGEdoesn't immediately split anything, just prevents future khugepaged collapses?Quoted 4 lines
Suggested-by Kevin Brodsky <[email protected]>Suggested-by Lorenzo Stoakes (ARM) <[email protected]>Signed-off-by Yeoreum Yun <[email protected]>LGTM, thanks, with a few nits above/below (sorry! :P)
Reviewed-by Lorenzo Stoakes (ARM) <[email protected]>tools/testing/selftests/mm/split_huge_page_test.c static char *allocate_zero_filled_hugepage(size_t len) · line 171
Quoted 13 lines
--- tools/testing/selftests/mm/split_huge_page_test.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)tools/testing/selftests/mm/split_huge_page_test.c +1
-0@@ -168,6 +168,14 @@ static char *allocate_zero_filled_hugepage(size_t len)return result; } +static void madv_nohuge (void *addr,size_t len)Maybe call it
disable_khugepaged()to make it explicit that's what this is doing rather than eliminating any THP pages in the range?
Quoted 8 lines
tools/testing/selftests/mm/split_huge_page_test.c static char *allocate_zero_filled_hugepage(size_t len) · line 172
Quoted 1 line
tools/testing/selftests/mm/split_huge_page_test.c +1
-0+{Maybe a comment here like:
/* * Disables khugepaged from collapsing THPs in range, existing THP * pages remain. */
Okay :) I'll modify in the next-round. Thanks!
[...]
Signature · 2 lines
Sincerely, Yeoreum Yun
PATCH v4 2/3 kselftest: mm: replace usage of /proc/self/smaps for check_huge_xxx() helper
In reply to Yeoreum YunSince glibc commit 321e1fc73f (“malloc: Enable 2MB THP by default on AArch64”), glibc may call madvise(MADV_HUGEPAGE) for sufficiently large allocations made by memalign().
The underlying VMA may start at a different address from the aligned address returned by memalign(). Furthermore, a subsequent madvise(MADV_HUGEPAGE) call does not split the VMA because the flag is already set.
This causes split_huge_page_test to fail because the check_huge_xxx() helpers incorrectly require the address returned by memalign() to match the VMA start address reported in /proc/self/smaps.
Instead of relying on /proc/self/smaps, use /proc/self/pagemap and /proc/kpageflags to detect huge-page mappings and large folios:
1. If hpage_size == pmd_pagesize, check PAGE_IS_HUGE instead of using check_large_folios(), since only the mapping type matters. This identifies PMD-mapped huge pages.
2. Otherwise, use check_large_folios() to detect large folios. This covers mTHP cases.
3. Check the folio flags according to the type of huge page.
--- tools/testing/selftests/mm/vm_util.c | 145 ++++++++++++++++++++++------------- tools/testing/selftests/mm/vm_util.h | 1 + 2 files changed, 92 insertions(+), 54 deletions(-)
tools/testing/selftests/mm/vm_util.c +91 -54
@@ -351,31 +351,13 @@ char *__get_smap_entry(void *addr, const char *pattern, char *buf, size_t len)return entry; } -static bool __check_pmd_huge (void *addr,char *pattern,int nr_hpages, -uint64_t hpage_size) -{ -char buffer[MAX_LINE_LENGTH ]; -uint64_t thp =-1 ; -char *entry; - - entry =__get_smap_entry (addr, pattern, buffer,sizeof (buffer)); -if (!entry) - goto err_out; - -if (sscanf (entry,"%9" SCNu64" kB" , &thp) !=1 ) -ksft_exit_fail_msg ("Reading smap error\n" ); - -err_out: -return thp == (nr_hpages * (hpage_size >>10 )); -} - -static bool check_large_folios (void *addr,size_t len,int nr_hpages, -uint64_t hpage_size) +static bool check_large_folios (int pagemap_fd,int kpageflags_fd, +void *addr,size_t len,int nr_hpages, +uint64_t hpage_size) {int order =0 , pagesize =getpagesize ();unsigned int nr_pages = hpage_size / pagesize;int orders[MAX_NR_ORDERS ], status; -int pagemap_fd, kpageflags_fd;bool ret = false;if (!nr_pages)
@@ -386,15 +368,6 @@ static bool check_large_folios(void *addr, size_t len, int nr_hpages,ksft_exit_fail_msg ("invalid order\n" );memset (orders,0 ,sizeof (int ) *MAX_NR_ORDERS ); - pagemap_fd =open (PAGEMAP_PATH ,O_RDONLY ); -if (pagemap_fd ==-1 ) -ksft_exit_fail_msg ("read pagemap fail\n" ); - - kpageflags_fd =open (KPAGEFLAGS_PATH ,O_RDONLY ); -if (kpageflags_fd ==-1 ) { -close (pagemap_fd); -ksft_exit_fail_msg ("read kpageflags fail\n" ); - } status =gather_folio_orders (addr, len, pagemap_fd, kpageflags_fd, orders,MAX_NR_ORDERS );
@@ -405,48 +378,112 @@ static bool check_large_folios(void *addr, size_t len, int nr_hpages, ret = true; out: -close (pagemap_fd); -close (kpageflags_fd);return ret; } -bool check_huge_anon (void *addr,size_t len,int nr_hpages,uint64_t hpage_size) -{ -uint64_t pmd_pagesize =read_pmd_pagesize (); - -if (!pmd_pagesize) -ksft_exit_fail_msg ("reading PMD pagesize failed\n" ); +enum check_huge_type { +CHECK_HUGE_ANON , +CHECK_HUGE_FILE , +CHECK_HUGE_SHMEM , +}; -if (hpage_size == pmd_pagesize) -return __check_pmd_huge (addr,"AnonHugePages: " , nr_hpages, hpage_size); +static bool check_huge_type (uint64_t categories,uint64_t kpageflags, +enum check_huge_type type) +{ +const bool file = categories &PAGE_IS_FILE ; +const bool swapbacked = kpageflags &KPF_SWAPBACKED ; + +switch (type) { +case CHECK_HUGE_ANON : +return !file; +case CHECK_HUGE_FILE : +return file && !swapbacked; +case CHECK_HUGE_SHMEM : +return file & swapbacked; + } -return check_large_folios (addr, len, nr_hpages, hpage_size); +return false; } -bool check_huge_file (void *addr,size_t len,int nr_hpages,uint64_t hpage_size) +static bool __check_huge (void *addr,size_t len,int nr_hpages, +uint64_t hpage_size,enum check_huge_type type) { -uint64_t pmd_pagesize =read_pmd_pagesize (); +bool ret = false; +int pagemap_fd, kpageflags_fd; +int nr_pmd_mappings =0 ; +uint64_t pmd_pagesize, scan_mapping_size; +uint64_t categories, kpf; +unsigned long pfn; +bool check_pmd_mapping, allow_nonpresent; +char *start = addr; +char *end = start + len; + pmd_pagesize =read_pmd_pagesize ();if (!pmd_pagesize)ksft_exit_fail_msg ("reading PMD pagesize failed\n" ); -if (hpage_size == pmd_pagesize) -return __check_pmd_huge (addr,"FilePmdMapped:" , nr_hpages, hpage_size); + check_pmd_mapping = (hpage_size == pmd_pagesize); + scan_mapping_size = (nr_hpages >0 ) ? hpage_size :psize (); +/* Some mTHP tests check a partially populated PMD-sized range. */ + allow_nonpresent = (uint64_t )nr_hpages * hpage_size < len; -return check_large_folios (addr, len, nr_hpages, hpage_size); + pagemap_fd =open (PAGEMAP_PATH ,O_RDONLY ); +if (pagemap_fd <0 ) +ksft_exit_fail_msg ("open pagemap fail\n" ); + + kpageflags_fd =open (KPAGEFLAGS_PATH ,O_RDONLY ); +if (kpageflags_fd <0 ) { +close (pagemap_fd); +ksft_exit_fail_msg ("open kpageflags fail\n" ); + } + +if (!check_pmd_mapping && + !check_large_folios (pagemap_fd, kpageflags_fd, + addr, len, nr_hpages, hpage_size)) + goto out; + +for (; start < end; start += scan_mapping_size) { + categories =pagemap_scan_get_categories (pagemap_fd, start); + pfn =pagemap_get_pfn (pagemap_fd, start); +if (pfn ==-1UL ) { +if (!allow_nonpresent) + goto out; +else +continue ; + } +if (pageflags_get (pfn, kpageflags_fd, &kpf)) +ksft_exit_fail_msg ("read kpageflags: %s\n" ,strerror (errno)); +if (check_pmd_mapping && (categories &PAGE_IS_HUGE )) + nr_pmd_mappings++; +if (kpf &KPF_COMPOUND_TAIL ) +continue ; +if (!check_huge_type (categories, kpf, type)) + goto out; + } + +if (check_pmd_mapping && (nr_pmd_mappings != nr_hpages)) + goto out; + ret = true; + +out: +close (pagemap_fd); +close (kpageflags_fd); +return ret; } -bool check_huge_shmem (void *addr,size_t len,int nr_hpages,uint64_t hpage_size) +bool check_huge_anon (void *addr,size_t len,int nr_hpages,uint64_t hpage_size) { -uint64_t pmd_pagesize =read_pmd_pagesize (); - -if (!pmd_pagesize) -ksft_exit_fail_msg ("reading PMD pagesize failed\n" ); +return __check_huge (addr, len, nr_hpages, hpage_size,CHECK_HUGE_ANON ); +} -if (hpage_size == pmd_pagesize) -return __check_pmd_huge (addr,"ShmemPmdMapped:" , nr_hpages, hpage_size); +bool check_huge_file (void *addr,size_t len,int nr_hpages,uint64_t hpage_size) +{ +return __check_huge (addr, len, nr_hpages, hpage_size,CHECK_HUGE_FILE ); +} -return check_large_folios (addr, len, nr_hpages, hpage_size); +bool check_huge_shmem (void *addr,size_t len,int nr_hpages,uint64_t hpage_size) +{ +return __check_huge (addr, len, nr_hpages, hpage_size,CHECK_HUGE_SHMEM ); }int64_t allocate_transhuge (void *ptr,int pagemap_fd)
tools/testing/selftests/mm/vm_util.h +1 -0
@@ -18,6 +18,7 @@#define PM_SWAP BIT_ULL(62)#define PM_PRESENT BIT_ULL(63) +#define KPF_SWAPBACKED BIT_ULL(14)#define KPF_COMPOUND_HEAD BIT_ULL(15)#define KPF_COMPOUND_TAIL BIT_ULL(16)#define KPF_HWPOISON BIT_ULL(19)
Signature · 1 line
2.43.0
PATCH v4 3/3 kselftest: mm: introduce alloc_isolated_mem()
In reply to Yeoreum YunSome MM tests use memalign() to allocate memory. However, the resulting memory area may unexpectedly merge with an adjacent VMA, causing tests that inspect it through /proc/self/smaps to fail.
Eliminate this potential source of test flakiness by introducing alloc_isolated_mem(), which places guard regions before and after the allocated area to prevent unexpected VMA merging.
Replace memalign() with this helper and use the helper in softdirty_supported() instead of mmap().
--- tools/testing/selftests/mm/pagemap_ioctl.c | 18 +++--- tools/testing/selftests/mm/soft-dirty.c | 6 +- tools/testing/selftests/mm/split_huge_page_test.c | 8 +-- tools/testing/selftests/mm/vm_util.c | 67 +++++++++++++++++++++-- tools/testing/selftests/mm/vm_util.h | 2 + 5 files changed, 81 insertions(+), 20 deletions(-)
tools/testing/selftests/mm/pagemap_ioctl.c +9 -9
@@ -792,9 +792,9 @@ void *gethugepage(int map_size)int ret;char *map; - map =memalign (hpage_size, map_size); + map =alloc_isolated_mem (hpage_size, map_size);if (!map) -ksft_exit_fail_msg ("memalign failed %d %s\n" , errno,strerror (errno)); +ksft_exit_fail_msg ("alloc_isolated_mem failed %d %s\n" , errno,strerror (errno)); ret =madvise (map, map_size,MADV_HUGEPAGE );if (ret)
@@ -856,7 +856,7 @@ int hpage_unit_tests(void)/* 4. only middle page written */ wp_free (map, map_size); -free (map); +free_isolated_mem (map, map_size); map =gethugepage (map_size);wp_init (map, map_size);wp_addr_range (map, map_size);
@@ -871,7 +871,7 @@ int hpage_unit_tests(void) "%s only middle page written\n", __func__);wp_free (map, map_size); -free (map); +free_isolated_mem (map, map_size); }else {ksft_test_result_skip ("%s all new huge page must be written\n" , __func__);ksft_test_result_skip ("%s all the huge page must not be written\n" , __func__);
@@ -898,7 +898,7 @@ int hpage_unit_tests(void) vec[0 ].start == (uintptr_t )(map + map_size/2 ), "%s clear first half of huge page\n", __func__);wp_free (map, map_size); -free (map); +free_isolated_mem (map, map_size); }else {ksft_test_result_skip ("%s clear first half of huge page\n" , __func__); }
@@ -927,7 +927,7 @@ int hpage_unit_tests(void)"%s clear first half of huge page with limited buffer\n" , __func__);wp_free (map, map_size); -free (map); +free_isolated_mem (map, map_size); }else {ksft_test_result_skip ("%s clear first half of huge page with limited buffer\n" , __func__);
@@ -955,7 +955,7 @@ int hpage_unit_tests(void)ksft_test_result (ret ==1 &&LEN (vec[0 ]) == vec_size/2 ,"%s clear second half huge page\n" , __func__);wp_free (map, map_size); -free (map); +free_isolated_mem (map, map_size); }else {ksft_test_result_skip ("%s clear second half huge page\n" , __func__); }
@@ -988,7 +988,7 @@ int hpage_unit_tests(void) "%s get half huge page\n", __func__);wp_free (map, map_size); -free (map); +free_isolated_mem (map, map_size); }else {ksft_test_result_skip ("%s get half huge page\n" , __func__);ksft_test_result_skip ("%s get half huge page\n" , __func__);
@@ -1702,7 +1702,7 @@ int main(int __attribute__((unused)) argc, char *argv[])wp_addr_range (map, hpage_size);base_tests ("Huge page testing:" , map, hpage_size,0 );wp_free (map, hpage_size); -free (map); +free_isolated_mem (map, hpage_size); }else {base_tests ("Huge page testing:" ,NULL ,0 ,1 ); }
tools/testing/selftests/mm/soft-dirty.c +3 -3
@@ -92,9 +92,9 @@ static void test_hugepage(int pagemap_fd, int pagesize)if (!hpage_len)ksft_exit_fail_msg ("Reading PMD pagesize failed" ); - map =memalign (hpage_len, hpage_len); + map =alloc_isolated_mem (hpage_len, hpage_len);if (!map) -ksft_exit_fail_msg ("memalign failed\n" ); +ksft_exit_fail_msg ("alloc_isolated_mem failed\n" ); ret =madvise (map, hpage_len,MADV_HUGEPAGE );if (ret)
@@ -130,7 +130,7 @@ static void test_hugepage(int pagemap_fd, int pagesize)ksft_test_result_skip ("Test %s huge page allocation\n" , __func__);ksft_test_result_skip ("Test %s huge page dirty bit\n" , __func__); } -free (map); +free_isolated_mem (map, hpage_len); }static void test_mprotect (int pagemap_fd,int pagesize,bool anon)
tools/testing/selftests/mm/split_huge_page_test.c +4 -4
@@ -154,7 +154,7 @@ static char *allocate_zero_filled_hugepage(size_t len)char *result;size_t i; - result =memalign (pmd_pagesize, len); + result =alloc_isolated_mem (pmd_pagesize, len);if (!result) {printf ("Fail to allocate memory\n" );exit (EXIT_FAILURE );
@@ -217,7 +217,7 @@ static void split_pmd_zero_pages(void) one_page =allocate_zero_filled_hugepage (len);verify_rss_anon_split_huge_page_all_zeroes (one_page, nr_hpages, len);ksft_test_result_pass ("Split zero filled huge pages successful\n" ); -free (one_page); +free_isolated_mem (one_page, len); }static void split_pmd_thp_to_order (int order)
@@ -226,7 +226,7 @@ static void split_pmd_thp_to_order(int order)size_t len =4 * pmd_pagesize;size_t i; - one_page =memalign (pmd_pagesize, len); + one_page =alloc_isolated_mem (pmd_pagesize, len);if (!one_page)ksft_exit_fail_msg ("Fail to allocate memory: %s\n" ,strerror (errno));
@@ -261,7 +261,7 @@ static void split_pmd_thp_to_order(int order)ksft_exit_fail_msg ("Still AnonHugePages not split\n" );ksft_test_result_pass ("Split huge pages to order %d successful\n" , order); -free (one_page); +free_isolated_mem (one_page, len); }static void split_pte_mapped_thp (void )
tools/testing/selftests/mm/vm_util.c +63 -4
88 lines not on this page · raw message
tools/testing/selftests/mm/vm_util.h +2 -0
@@ -95,6 +95,8 @@ bool check_huge_anon(void *addr, size_t len, int nr_hpages, uint64_t hpage_size)bool check_huge_file (void *addr,size_t len,int nr_hpages,uint64_t hpage_size);bool check_huge_shmem (void *addr,size_t len,int nr_hpages,uint64_t hpage_size);int64_t allocate_transhuge (void *ptr,int pagemap_fd); +void *alloc_isolated_mem (size_t align,size_t size); +void free_isolated_mem (void *addr,size_t size);int pageflags_get (unsigned long pfn,int kpageflags_fd,uint64_t *flags);int gather_folio_orders (char *vaddr_start,size_t len,int pagemap_fd,int kpageflags_fd,int orders[],int nr_orders);
Signature · 1 line
2.43.0