* [PATCH 00/53] selftests/mm: make MM selftests more CI friendly
@ 2026-04-06 14:16 Mike Rapoport
2026-04-06 14:16 ` [PATCH 01/53] selftests/mm: hugetlb-read-hwpoison: add SIGBUS handler Mike Rapoport
` (52 more replies)
0 siblings, 53 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Hi,
There's a lot of dancing around HugeTLB settings in run_vmtests.sh.
Some test need just a few default huge pages, some require at least 256 MB, and
some just skip lots of tests if huge pages of all supported sizes are not
available.
The goal of this set is to make tests deal with HugeTLB setup and teardown.
There are already convenient helpers that allow easy reading and writing of
/proc and /sysfs, so adding a few APIs that will detect and update HugeTLB
settings shouldn't be a big deal. But these nice helpers use kselftest
framework, and many of HugeTLB (and even THP) test don't, so as a result this
patchset also includes a lot of churn for conversion of those tests to
kselftest framework (patches 7-19).
And there were a few small things I fixed on the way.
I don't mean for this set to land in 7.1-rc1, except perhaps the small fixes in
the beginning of the series (patches 1-4).
But after staring at this code for some time I realized that I won't spot any
new issues in these patches and an extra pair(s) of eyes would be helpful.
The extension of thp_settings to hugepage_settings that also include HugeTLB
helpers is implemented by patches 20-26.
Patches 27-28 are there to allow setting up SHM limits in hugetlb-shm and
thuge-gen tests.
Patches 29-51 integrate the new APIs in all the tests that use HugeTLB.
And at last patches 52-53 drop HugeTLB setup from run_vmtests.sh
Happy Easter to those who celebrate!
Mike Rapoport (Microsoft) (53):
selftests/mm: hugetlb-read-hwpoison: add SIGBUS handler
selftests/mm: khugepaged: enable collapse_single_pte_entry_compound for shmem
selftests/mm: migration: don't assume hupe page is TWOMEG
selftests/mm: run_vmtests.sh: don't gate THP and KSM tests on HAVE_HUGEPAGES
selftests/mm: merge map_hugetlb into hugepage-mmap
selftests/mm: rename hugepage-* tests to hugetlb-*
selftests/mm: hugetlb-shm: use kselftest framework
selftests/mm: hugetlb-vmemmap: use kselftest framework
selftests/mm: hugetlb-madvise: use kselftest framework
selftests/mm: hugetlb_madv_vs_map: use kselftest framework
selftests/mm: hugetlb-read-hwpoison: use kselftest framework
selftests/mm: khugepaged: group tests in an array
selftests/mm: khugepaged: use ksefltest framework
selftests/mm: ksm_tests: use kselftest framework
selftests/mm: protection_keys: use descriptive test names in TAP output
selftests/mm: protection_keys: use kselftest framework
selftests/mm: uffd-stress: use kselftest framework
selftests/mm: uffd-unit-tests: use kselftest framework
selftests/mm: va_high_addr_switch: use kselftest framework
selftests/mm: add atexit() and signal handlers to thp_settings
selftests/mm: rename thp_settings.[ch] to hugepage_settings.[ch]
selftests/mm: move HugeTLB helpers to hugepage_settings
selftests/mm: hugepage_settings: use unsigned long in detect_hugetlb_page_size
selftests/mm: hugepage_settings: add APIs to get and set nr_hugepages
selftests/mm: hugepage_settings: rename get_free_hugepages()
selftests/mm: hugepage_settings: add APIs for HugeTLB setup and teardown
selftests/mm: move read_file(), read_num() and write_num() to vm_util
selftests/mm: vm_util: add helpers to set and restore shm limits
selftests/mm: compaction_test: use HugeTLB helpers ...
selftests/mm: cow: add setup of HugeTLB pages
selftests/mm: gup_longterm: add setup of HugeTLB pages
selftests/mm: gup_test: add setup of HugeTLB pages
selftests/mm: hmm-tests: add setup of HugeTLB pages
selftests/mm: hugepage_dio: add setup of HugeTLB pages
selftests/mm: hugetlb_fault_after_madv: add setup of HugeTLB pages
selftests/mm: hugetlb-madvise: add setup of HugeTLB pages
selftests/mm: hugetlb_madv_vs_map: add setup of HugeTLB pages
selftests/mm: hugetlb-mmap: add setup of HugeTLB pages
selftests/mm: hugetlb-mremap: add setup of HugeTLB pages
selftests/mm: hugetlb-shm: add setup of HugeTLB pages
selftests/mm: hugetlb-soft-online: add setup of HugeTLB pages
selftests/mm: hugetlb-vmemmap: add setup of HugeTLB pages
selftests/mm: migration: add setup of HugeTLB pages
selftests/mm: pagemap_ioctl: add setup of HugeTLB pages
selftests/mm: protection_keys: use library code for HugeTLB setup
selftests/mm: thuge-gen: add setup of HugeTLB pages
selftests/mm: uffd-stress: use hugetlb_save and alloc huge pages
selftests/mm: uffd-unit-tests: add setup of HugeTLB pages
selftests/mm: uffd-wp-mremap: add setup of HugeTLB pages
selftests/mm: va_high_addr_switch: add setup of HugeTLB pages
selftests/mm: va_high_addr_switch.sh: drop huge pages setup
selftests/mm: run_vmtests.sh: free memory if available memory is low
selftests/mm: run_vmtests.sh: drop detection and setup of HugeTLB
tools/testing/selftests/mm/.gitignore | 4 +
tools/testing/selftests/mm/Makefile | 13 +-
tools/testing/selftests/mm/compaction_test.c | 113 +----
tools/testing/selftests/mm/cow.c | 29 +-
.../selftests/mm/folio_split_race_test.c | 2 +-
tools/testing/selftests/mm/guard-regions.c | 2 +-
tools/testing/selftests/mm/gup_longterm.c | 3 +-
tools/testing/selftests/mm/gup_test.c | 12 +
tools/testing/selftests/mm/hmm-tests.c | 24 +-
tools/testing/selftests/mm/hugepage-mmap.c | 78 ----
.../{thp_settings.c => hugepage_settings.c} | 284 +++++++++++--
.../{thp_settings.h => hugepage_settings.h} | 75 +++-
tools/testing/selftests/mm/hugetlb-madvise.c | 209 ++++------
tools/testing/selftests/mm/hugetlb-mmap.c | 141 +++++++
.../{hugepage-mremap.c => hugetlb-mremap.c} | 13 +-
.../selftests/mm/hugetlb-read-hwpoison.c | 123 +++---
.../mm/{hugepage-shm.c => hugetlb-shm.c} | 65 ++-
.../selftests/mm/hugetlb-soft-offline.c | 45 +-
.../{hugepage-vmemmap.c => hugetlb-vmemmap.c} | 46 +-
tools/testing/selftests/mm/hugetlb_dio.c | 15 +-
.../selftests/mm/hugetlb_fault_after_madv.c | 7 +-
.../selftests/mm/hugetlb_madv_vs_map.c | 22 +-
tools/testing/selftests/mm/khugepaged.c | 394 ++++++++----------
tools/testing/selftests/mm/ksm_tests.c | 182 ++++----
tools/testing/selftests/mm/map_hugetlb.c | 88 ----
tools/testing/selftests/mm/migration.c | 54 ++-
tools/testing/selftests/mm/pagemap_ioctl.c | 13 +-
tools/testing/selftests/mm/pkey-helpers.h | 6 +-
.../testing/selftests/mm/prctl_thp_disable.c | 2 +-
tools/testing/selftests/mm/protection_keys.c | 131 +++---
tools/testing/selftests/mm/run_vmtests.sh | 177 ++------
tools/testing/selftests/mm/soft-dirty.c | 2 +-
.../selftests/mm/split_huge_page_test.c | 2 +-
tools/testing/selftests/mm/thuge-gen.c | 80 +---
tools/testing/selftests/mm/transhuge-stress.c | 2 +-
tools/testing/selftests/mm/uffd-common.h | 1 +
tools/testing/selftests/mm/uffd-stress.c | 44 +-
tools/testing/selftests/mm/uffd-unit-tests.c | 110 +++--
tools/testing/selftests/mm/uffd-wp-mremap.c | 12 +-
.../selftests/mm/va_high_addr_switch.c | 40 +-
.../selftests/mm/va_high_addr_switch.sh | 39 +-
tools/testing/selftests/mm/vm_util.c | 133 +++---
tools/testing/selftests/mm/vm_util.h | 15 +-
43 files changed, 1377 insertions(+), 1475 deletions(-)
delete mode 100644 tools/testing/selftests/mm/hugepage-mmap.c
rename tools/testing/selftests/mm/{thp_settings.c => hugepage_settings.c} (60%)
rename tools/testing/selftests/mm/{thp_settings.h => hugepage_settings.h} (55%)
create mode 100644 tools/testing/selftests/mm/hugetlb-mmap.c
rename tools/testing/selftests/mm/{hugepage-mremap.c => hugetlb-mremap.c} (94%)
rename tools/testing/selftests/mm/{hugepage-shm.c => hugetlb-shm.c} (56%)
rename tools/testing/selftests/mm/{hugepage-vmemmap.c => hugetlb-vmemmap.c} (76%)
delete mode 100644 tools/testing/selftests/mm/map_hugetlb.c
base-commit: 9a5c21a0791faf7967feea87f8f345419330bd2f
--
2.53.0
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH 01/53] selftests/mm: hugetlb-read-hwpoison: add SIGBUS handler
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:16 ` [PATCH 02/53] selftests/mm: khugepaged: enable collapse_single_pte_entry_compound for shmem Mike Rapoport
` (51 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Access of poisoned memory causes SIGBUS, which terminates the
hugetlb-read-hwpoison test prematurely.
Add a dummy SIGBUS handler to allow the test to continue regardless of
SIGBUS.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb-read-hwpoison.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tools/testing/selftests/mm/hugetlb-read-hwpoison.c b/tools/testing/selftests/mm/hugetlb-read-hwpoison.c
index 46230462ad48..6bbf15f78061 100644
--- a/tools/testing/selftests/mm/hugetlb-read-hwpoison.c
+++ b/tools/testing/selftests/mm/hugetlb-read-hwpoison.c
@@ -10,6 +10,7 @@
#include <sys/statfs.h>
#include <errno.h>
#include <stdbool.h>
+#include <signal.h>
#include "kselftest.h"
@@ -261,6 +262,11 @@ static int create_hugetlbfs_file(struct statfs *file_stat)
return -1;
}
+static void sigbus_handler(int sig)
+{
+ printf(PREFIX "received SIGBUS\n");
+}
+
int main(void)
{
int fd;
@@ -273,6 +279,7 @@ int main(void)
};
size_t i;
+ signal(SIGBUS, sigbus_handler);
for (i = 0; i < ARRAY_SIZE(wr_chunk_sizes); ++i) {
printf("Write/read chunk size=0x%lx\n",
wr_chunk_sizes[i]);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 02/53] selftests/mm: khugepaged: enable collapse_single_pte_entry_compound for shmem
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
2026-04-06 14:16 ` [PATCH 01/53] selftests/mm: hugetlb-read-hwpoison: add SIGBUS handler Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:16 ` [PATCH 03/53] selftests/mm: migration: don't assume hupe page is TWOMEG Mike Rapoport
` (50 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
A comment in collapse_single_pte_entry_compound() says it can't run on
shmem because "MADV_DONTNEED can't evict tmpfs pages".
But MADV_REMOVE can!
Use MADV_REMOVE for tmpfs to evict pages and enable
collapse_single_pte_entry_compound() test for shmem.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/khugepaged.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c
index 3fe7ef04ac62..e6fb01ca44ed 100644
--- a/tools/testing/selftests/mm/khugepaged.c
+++ b/tools/testing/selftests/mm/khugepaged.c
@@ -783,20 +783,17 @@ static void collapse_max_ptes_swap(struct collapse_context *c, struct mem_ops *o
static void collapse_single_pte_entry_compound(struct collapse_context *c, struct mem_ops *ops)
{
+ int advise = MADV_DONTNEED;
void *p;
p = alloc_hpage(ops);
- if (is_tmpfs(ops)) {
- /* MADV_DONTNEED won't evict tmpfs pages */
- printf("tmpfs...");
- skip("Skip");
- goto skip;
- }
+ if (is_tmpfs(ops))
+ advise = MADV_REMOVE;
madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);
printf("Split huge page leaving single PTE mapping compound page...");
- madvise(p + page_size, hpage_pmd_size - page_size, MADV_DONTNEED);
+ madvise(p + page_size, hpage_pmd_size - page_size, advise);
if (ops->check_huge(p, 0))
success("OK");
else
@@ -805,7 +802,6 @@ static void collapse_single_pte_entry_compound(struct collapse_context *c, struc
c->collapse("Collapse PTE table with single PTE mapping compound page",
p, 1, ops, true);
validate_memory(p, 0, page_size);
-skip:
ops->cleanup_area(p, hpage_pmd_size);
}
@@ -1251,8 +1247,10 @@ int main(int argc, char **argv)
TEST(collapse_single_pte_entry_compound, khugepaged_context, anon_ops);
TEST(collapse_single_pte_entry_compound, khugepaged_context, file_ops);
+ TEST(collapse_single_pte_entry_compound, khugepaged_context, shmem_ops);
TEST(collapse_single_pte_entry_compound, madvise_context, anon_ops);
TEST(collapse_single_pte_entry_compound, madvise_context, file_ops);
+ TEST(collapse_single_pte_entry_compound, madvise_context, shmem_ops);
TEST(collapse_full_of_compound, khugepaged_context, anon_ops);
TEST(collapse_full_of_compound, khugepaged_context, file_ops);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 03/53] selftests/mm: migration: don't assume hupe page is TWOMEG
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
2026-04-06 14:16 ` [PATCH 01/53] selftests/mm: hugetlb-read-hwpoison: add SIGBUS handler Mike Rapoport
2026-04-06 14:16 ` [PATCH 02/53] selftests/mm: khugepaged: enable collapse_single_pte_entry_compound for shmem Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:16 ` [PATCH 04/53] selftests/mm: run_vmtests.sh: don't gate THP and KSM tests on HAVE_HUGEPAGES Mike Rapoport
` (49 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
migration tests presume that both THP and HugeTLB huge pages are 2MB.
Add dynamic detection of huge page size with read_pmd_pagesize() for THP
and with default_huge_page_size() for HugeTLB.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/migration.c | 44 +++++++++++++++++++-------
1 file changed, 32 insertions(+), 12 deletions(-)
diff --git a/tools/testing/selftests/mm/migration.c b/tools/testing/selftests/mm/migration.c
index 60e78bbfc0e3..e3c2f831e15a 100644
--- a/tools/testing/selftests/mm/migration.c
+++ b/tools/testing/selftests/mm/migration.c
@@ -184,22 +184,27 @@ TEST_F_TIMEOUT(migration, shared_anon, 2*RUNTIME)
*/
TEST_F_TIMEOUT(migration, private_anon_thp, 2*RUNTIME)
{
+ unsigned long pmdsize;
uint64_t *ptr;
int i;
if (!thp_is_enabled())
SKIP(return, "Transparent Hugepages not available");
+ pmdsize = read_pmd_pagesize();
+ if (!pmdsize)
+ SKIP(return, "Reading PMD pagesize failed");
+
if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
SKIP(return, "Not enough threads or NUMA nodes available");
- ptr = mmap(NULL, 2*TWOMEG, PROT_READ | PROT_WRITE,
+ ptr = mmap(NULL, 2 * pmdsize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_NE(ptr, MAP_FAILED);
- ptr = (uint64_t *) ALIGN((uintptr_t) ptr, TWOMEG);
- ASSERT_EQ(madvise(ptr, TWOMEG, MADV_HUGEPAGE), 0);
- memset(ptr, 0xde, TWOMEG);
+ ptr = (uint64_t *) ALIGN((uintptr_t) ptr, pmdsize);
+ ASSERT_EQ(madvise(ptr, pmdsize, MADV_HUGEPAGE), 0);
+ memset(ptr, 0xde, pmdsize);
for (i = 0; i < self->nthreads - 1; i++)
if (pthread_create(&self->threads[i], NULL, access_mem, ptr))
perror("Couldn't create thread");
@@ -215,6 +220,7 @@ TEST_F_TIMEOUT(migration, private_anon_thp, 2*RUNTIME)
TEST_F_TIMEOUT(migration, shared_anon_thp, 2*RUNTIME)
{
+ unsigned long pmdsize;
pid_t pid;
uint64_t *ptr;
int i;
@@ -222,17 +228,21 @@ TEST_F_TIMEOUT(migration, shared_anon_thp, 2*RUNTIME)
if (!thp_is_enabled())
SKIP(return, "Transparent Hugepages not available");
+ pmdsize = read_pmd_pagesize();
+ if (!pmdsize)
+ SKIP(return, "Reading PMD pagesize failed");
+
if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
SKIP(return, "Not enough threads or NUMA nodes available");
- ptr = mmap(NULL, 2 * TWOMEG, PROT_READ | PROT_WRITE,
+ ptr = mmap(NULL, 2 * pmdsize, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
ASSERT_NE(ptr, MAP_FAILED);
- ptr = (uint64_t *) ALIGN((uintptr_t) ptr, TWOMEG);
- ASSERT_EQ(madvise(ptr, TWOMEG, MADV_HUGEPAGE), 0);
+ ptr = (uint64_t *) ALIGN((uintptr_t) ptr, pmdsize);
+ ASSERT_EQ(madvise(ptr, pmdsize, MADV_HUGEPAGE), 0);
- memset(ptr, 0xde, TWOMEG);
+ memset(ptr, 0xde, pmdsize);
for (i = 0; i < self->nthreads - 1; i++) {
pid = fork();
if (!pid) {
@@ -256,17 +266,22 @@ TEST_F_TIMEOUT(migration, shared_anon_thp, 2*RUNTIME)
*/
TEST_F_TIMEOUT(migration, private_anon_htlb, 2*RUNTIME)
{
+ unsigned long hugepage_size;
uint64_t *ptr;
int i;
if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
SKIP(return, "Not enough threads or NUMA nodes available");
- ptr = mmap(NULL, TWOMEG, PROT_READ | PROT_WRITE,
+ hugepage_size = default_huge_page_size();
+ if (!hugepage_size)
+ SKIP(return, "Reading HugeTLB pagesize failed\n");
+
+ ptr = mmap(NULL, hugepage_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
ASSERT_NE(ptr, MAP_FAILED);
- memset(ptr, 0xde, TWOMEG);
+ memset(ptr, 0xde, hugepage_size);
for (i = 0; i < self->nthreads - 1; i++)
if (pthread_create(&self->threads[i], NULL, access_mem, ptr))
perror("Couldn't create thread");
@@ -281,6 +296,7 @@ TEST_F_TIMEOUT(migration, private_anon_htlb, 2*RUNTIME)
*/
TEST_F_TIMEOUT(migration, shared_anon_htlb, 2*RUNTIME)
{
+ unsigned long hugepage_size;
pid_t pid;
uint64_t *ptr;
int i;
@@ -288,11 +304,15 @@ TEST_F_TIMEOUT(migration, shared_anon_htlb, 2*RUNTIME)
if (self->nthreads < 2 || self->n1 < 0 || self->n2 < 0)
SKIP(return, "Not enough threads or NUMA nodes available");
- ptr = mmap(NULL, TWOMEG, PROT_READ | PROT_WRITE,
+ hugepage_size = default_huge_page_size();
+ if (!hugepage_size)
+ SKIP(return, "Reading HugeTLB pagesize failed\n");
+
+ ptr = mmap(NULL, hugepage_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
ASSERT_NE(ptr, MAP_FAILED);
- memset(ptr, 0xde, TWOMEG);
+ memset(ptr, 0xde, hugepage_size);
for (i = 0; i < self->nthreads - 1; i++) {
pid = fork();
if (!pid) {
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 04/53] selftests/mm: run_vmtests.sh: don't gate THP and KSM tests on HAVE_HUGEPAGES
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (2 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 03/53] selftests/mm: migration: don't assume hupe page is TWOMEG Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:16 ` [PATCH 05/53] selftests/mm: merge map_hugetlb into hugepage-mmap Mike Rapoport
` (48 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
HAVE_HUGEPAGES indicates availability of free HugeTLB pages. It should not
be used to gate KSM test that merges transparent huge pages or
split_huge_page_test.
Remove check for HAVE_HUGEPAGES when running these tests.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/run_vmtests.sh | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh
index d8468451b3a3..e2dc9ac87bfc 100755
--- a/tools/testing/selftests/mm/run_vmtests.sh
+++ b/tools/testing/selftests/mm/run_vmtests.sh
@@ -436,9 +436,7 @@ CATEGORY="memfd_secret" run_test ./memfd_secret
fi
# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100
-if [ "${HAVE_HUGEPAGES}" = "1" ]; then
- CATEGORY="ksm" run_test ./ksm_tests -H -s 100
-fi
+CATEGORY="ksm" run_test ./ksm_tests -H -s 100
# KSM KSM_MERGE_TIME test with size of 100
CATEGORY="ksm" run_test ./ksm_tests -P -s 100
# KSM MADV_MERGEABLE test with 10 identical pages
@@ -493,16 +491,14 @@ CATEGORY="thp" run_test ./transhuge-stress -d 20
# Try to create XFS if not provided
if [ -z "${SPLIT_HUGE_PAGE_TEST_XFS_PATH}" ]; then
- if [ "${HAVE_HUGEPAGES}" = "1" ]; then
- if test_selected "thp"; then
- if grep xfs /proc/filesystems &>/dev/null; then
- XFS_IMG=$(mktemp /tmp/xfs_img_XXXXXX)
- SPLIT_HUGE_PAGE_TEST_XFS_PATH=$(mktemp -d /tmp/xfs_dir_XXXXXX)
- truncate -s 314572800 ${XFS_IMG}
- mkfs.xfs -q ${XFS_IMG}
- mount -o loop ${XFS_IMG} ${SPLIT_HUGE_PAGE_TEST_XFS_PATH}
- MOUNTED_XFS=1
- fi
+ if test_selected "thp"; then
+ if grep xfs /proc/filesystems &>/dev/null; then
+ XFS_IMG=$(mktemp /tmp/xfs_img_XXXXXX)
+ SPLIT_HUGE_PAGE_TEST_XFS_PATH=$(mktemp -d /tmp/xfs_dir_XXXXXX)
+ truncate -s 314572800 ${XFS_IMG}
+ mkfs.xfs -q ${XFS_IMG}
+ mount -o loop ${XFS_IMG} ${SPLIT_HUGE_PAGE_TEST_XFS_PATH}
+ MOUNTED_XFS=1
fi
fi
fi
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 05/53] selftests/mm: merge map_hugetlb into hugepage-mmap
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (3 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 04/53] selftests/mm: run_vmtests.sh: don't gate THP and KSM tests on HAVE_HUGEPAGES Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:16 ` [PATCH 06/53] selftests/mm: rename hugepage-* tests to hugetlb-* Mike Rapoport
` (47 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Both tests create a hugettlb mapping, fill it with data and verify the
data, the only difference is that one uses file-backed memory and another
one uses anonymous memory.
Merge both tests into a single file.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/Makefile | 1 -
tools/testing/selftests/mm/hugepage-mmap.c | 113 ++++++++++++++++-----
tools/testing/selftests/mm/map_hugetlb.c | 88 ----------------
tools/testing/selftests/mm/run_vmtests.sh | 1 -
4 files changed, 86 insertions(+), 117 deletions(-)
delete mode 100644 tools/testing/selftests/mm/map_hugetlb.c
diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index cd24596cdd27..cbda989f6b6a 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -70,7 +70,6 @@ TEST_GEN_FILES += hugepage-vmemmap
TEST_GEN_FILES += khugepaged
TEST_GEN_FILES += madv_populate
TEST_GEN_FILES += map_fixed_noreplace
-TEST_GEN_FILES += map_hugetlb
TEST_GEN_FILES += map_populate
ifneq (,$(filter $(ARCH),arm64 riscv riscv64 x86 x86_64 loongarch32 loongarch64))
TEST_GEN_FILES += memfd_secret
diff --git a/tools/testing/selftests/mm/hugepage-mmap.c b/tools/testing/selftests/mm/hugepage-mmap.c
index d543419de040..de210043045a 100644
--- a/tools/testing/selftests/mm/hugepage-mmap.c
+++ b/tools/testing/selftests/mm/hugepage-mmap.c
@@ -15,6 +15,7 @@
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
+#include "vm_util.h"
#include "kselftest.h"
#define LENGTH (256UL*1024*1024)
@@ -25,54 +26,112 @@ static void check_bytes(char *addr)
ksft_print_msg("First hex is %x\n", *((unsigned int *)addr));
}
-static void write_bytes(char *addr)
+static void write_bytes(char *addr, size_t length)
{
unsigned long i;
- for (i = 0; i < LENGTH; i++)
+ for (i = 0; i < length; i++)
*(addr + i) = (char)i;
}
-static int read_bytes(char *addr)
+static bool verify_bytes(char *addr, size_t length)
{
unsigned long i;
check_bytes(addr);
- for (i = 0; i < LENGTH; i++)
- if (*(addr + i) != (char)i) {
- ksft_print_msg("Error: Mismatch at %lu\n", i);
- return 1;
- }
- return 0;
+ for (i = 0; i < length; i++)
+ if (*(addr + i) != (char)i)
+ return false;
+
+ return true;
}
-int main(void)
+static bool test_mmap(size_t length, int mmap_flags, int fd,
+ const char *test_name)
{
+ int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB;
void *addr;
- int fd, ret;
- ksft_print_header();
- ksft_set_plan(1);
+ addr = mmap(NULL, length, PROTECTION, flags, -1, 0);
+ if (addr == MAP_FAILED)
+ ksft_exit_fail_perror("mmap");
+
+ ksft_print_msg("Returned address is %p\n", addr);
+ check_bytes(addr);
+ write_bytes(addr, length);
+ if (!verify_bytes(addr, length))
+ ksft_exit_fail_msg("%s\n", test_name);
+
+ /* munmap() length of MAP_HUGETLB memory must be hugepage aligned */
+ if (munmap(addr, length))
+ ksft_exit_fail_perror("munmap");
+
+ return true;
+}
+
+static void test_anon_mmap(size_t length, int shift)
+{
+ const char *test_name = "hugetlb anonymous mmap";
+ int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB;
+ bool passed;
+
+ if (shift)
+ mmap_flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
+
+ passed = test_mmap(length, mmap_flags, -1, test_name);
+ ksft_test_result(passed, "%s\n", test_name);
+}
+
+static void test_file_mmap(size_t length, int shift)
+{
+ const char *test_name = "hugetlb file mmap";
+ int mmap_flags = MAP_SHARED;
+ bool passed;
+ int fd;
+
+ if (shift)
+ mmap_flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
- fd = memfd_create("hugepage-mmap", MFD_HUGETLB);
+ fd = memfd_create("hugetlb-mmap", MFD_HUGETLB);
if (fd < 0)
- ksft_exit_fail_msg("memfd_create() failed: %s\n", strerror(errno));
+ ksft_exit_fail_perror("memfd_create");
+
+ passed = test_mmap(length, mmap_flags, fd, test_name);
+
+ close(fd);
+ ksft_test_result(passed, "%s\n", test_name);
+}
+
+int main(int argc, char **argv)
+{
+ size_t hugepage_size;
+ size_t length = LENGTH;
+ int shift = 0;
+
+ ksft_print_header();
+ ksft_set_plan(2);
+
+ if (argc > 1)
+ length = atol(argv[1]) << 20;
+ if (argc > 2)
+ shift = atoi(argv[2]);
- addr = mmap(NULL, LENGTH, PROTECTION, MAP_SHARED, fd, 0);
- if (addr == MAP_FAILED) {
- close(fd);
- ksft_exit_fail_msg("mmap(): %s\n", strerror(errno));
+ if (shift) {
+ hugepage_size = (1 << shift);
+ ksft_print_msg("%u kB hugepages\n", 1 << (shift - 10));
+ } else {
+ hugepage_size = default_huge_page_size();
+ ksft_print_msg("Default size hugepages (%lu Kb)\n", hugepage_size >> 10);
}
- ksft_print_msg("Returned address is %p\n", addr);
- check_bytes(addr);
- write_bytes(addr);
- ret = read_bytes(addr);
+ /* munmap with fail if the length is not page aligned */
+ if (hugepage_size > length)
+ length = hugepage_size;
- munmap(addr, LENGTH);
- close(fd);
+ ksft_print_msg("Mapping %lu Mbytes\n", (unsigned long)length >> 20);
- ksft_test_result(!ret, "Read same data\n");
+ test_anon_mmap(length, shift);
+ test_file_mmap(length, shift);
- ksft_exit(!ret);
+ ksft_finished();
}
diff --git a/tools/testing/selftests/mm/map_hugetlb.c b/tools/testing/selftests/mm/map_hugetlb.c
deleted file mode 100644
index aa409107611b..000000000000
--- a/tools/testing/selftests/mm/map_hugetlb.c
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Example of using hugepage memory in a user application using the mmap
- * system call with MAP_HUGETLB flag. Before running this program make
- * sure the administrator has allocated enough default sized huge pages
- * to cover the 256 MB allocation.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include "vm_util.h"
-#include "kselftest.h"
-
-#define LENGTH (256UL*1024*1024)
-#define PROTECTION (PROT_READ | PROT_WRITE)
-
-static void check_bytes(char *addr)
-{
- ksft_print_msg("First hex is %x\n", *((unsigned int *)addr));
-}
-
-static void write_bytes(char *addr, size_t length)
-{
- unsigned long i;
-
- for (i = 0; i < length; i++)
- *(addr + i) = (char)i;
-}
-
-static void read_bytes(char *addr, size_t length)
-{
- unsigned long i;
-
- check_bytes(addr);
- for (i = 0; i < length; i++)
- if (*(addr + i) != (char)i)
- ksft_exit_fail_msg("Mismatch at %lu\n", i);
-
- ksft_test_result_pass("Read correct data\n");
-}
-
-int main(int argc, char **argv)
-{
- void *addr;
- size_t hugepage_size;
- size_t length = LENGTH;
- int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB;
- int shift = 0;
-
- hugepage_size = default_huge_page_size();
- /* munmap with fail if the length is not page aligned */
- if (hugepage_size > length)
- length = hugepage_size;
-
- ksft_print_header();
- ksft_set_plan(1);
-
- if (argc > 1)
- length = atol(argv[1]) << 20;
- if (argc > 2) {
- shift = atoi(argv[2]);
- if (shift)
- flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
- }
-
- if (shift)
- ksft_print_msg("%u kB hugepages\n", 1 << (shift - 10));
- else
- ksft_print_msg("Default size hugepages\n");
- ksft_print_msg("Mapping %lu Mbytes\n", (unsigned long)length >> 20);
-
- addr = mmap(NULL, length, PROTECTION, flags, -1, 0);
- if (addr == MAP_FAILED)
- ksft_exit_fail_msg("mmap: %s\n", strerror(errno));
-
- ksft_print_msg("Returned address is %p\n", addr);
- check_bytes(addr);
- write_bytes(addr, length);
- read_bytes(addr, length);
-
- /* munmap() length of MAP_HUGETLB memory must be hugepage aligned */
- if (munmap(addr, length))
- ksft_exit_fail_msg("munmap: %s\n", strerror(errno));
-
- ksft_finished();
-}
diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh
index e2dc9ac87bfc..61b450032af8 100755
--- a/tools/testing/selftests/mm/run_vmtests.sh
+++ b/tools/testing/selftests/mm/run_vmtests.sh
@@ -292,7 +292,6 @@ CATEGORY="hugetlb" run_test ./hugepage-shm
echo "$shmmax" > /proc/sys/kernel/shmmax
echo "$shmall" > /proc/sys/kernel/shmall
-CATEGORY="hugetlb" run_test ./map_hugetlb
CATEGORY="hugetlb" run_test ./hugepage-mremap
CATEGORY="hugetlb" run_test ./hugepage-vmemmap
CATEGORY="hugetlb" run_test ./hugetlb-madvise
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 06/53] selftests/mm: rename hugepage-* tests to hugetlb-*
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (4 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 05/53] selftests/mm: merge map_hugetlb into hugepage-mmap Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:16 ` [PATCH 07/53] selftests/mm: hugetlb-shm: use kselftest framework Mike Rapoport
` (46 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugepage could mean both THP and HugeTLB these days.
Rename hugepage-* tests for HugeTLB to hugetlb-* to avoid confusion.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/.gitignore | 4 ++++
tools/testing/selftests/mm/Makefile | 8 ++++----
tools/testing/selftests/mm/hugetlb-madvise.c | 2 +-
.../selftests/mm/{hugepage-mmap.c => hugetlb-mmap.c} | 2 +-
.../selftests/mm/{hugepage-mremap.c => hugetlb-mremap.c} | 2 +-
.../selftests/mm/{hugepage-shm.c => hugetlb-shm.c} | 2 +-
.../mm/{hugepage-vmemmap.c => hugetlb-vmemmap.c} | 0
tools/testing/selftests/mm/run_vmtests.sh | 8 ++++----
8 files changed, 16 insertions(+), 12 deletions(-)
rename tools/testing/selftests/mm/{hugepage-mmap.c => hugetlb-mmap.c} (99%)
rename tools/testing/selftests/mm/{hugepage-mremap.c => hugetlb-mremap.c} (99%)
rename tools/testing/selftests/mm/{hugepage-shm.c => hugetlb-shm.c} (99%)
rename tools/testing/selftests/mm/{hugepage-vmemmap.c => hugetlb-vmemmap.c} (100%)
diff --git a/tools/testing/selftests/mm/.gitignore b/tools/testing/selftests/mm/.gitignore
index b0c30c5ee9e3..9ccd9e1447e6 100644
--- a/tools/testing/selftests/mm/.gitignore
+++ b/tools/testing/selftests/mm/.gitignore
@@ -4,6 +4,10 @@ hugepage-mmap
hugepage-mremap
hugepage-shm
hugepage-vmemmap
+hugetlb-mmap
+hugetlb-mremap
+hugetlb-shm
+hugetlb-vmemmap
hugetlb-madvise
hugetlb-read-hwpoison
hugetlb-soft-offline
diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index cbda989f6b6a..a6955660a806 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -63,10 +63,10 @@ TEST_GEN_FILES += hmm-tests
TEST_GEN_FILES += hugetlb-madvise
TEST_GEN_FILES += hugetlb-read-hwpoison
TEST_GEN_FILES += hugetlb-soft-offline
-TEST_GEN_FILES += hugepage-mmap
-TEST_GEN_FILES += hugepage-mremap
-TEST_GEN_FILES += hugepage-shm
-TEST_GEN_FILES += hugepage-vmemmap
+TEST_GEN_FILES += hugetlb-mremap
+TEST_GEN_FILES += hugetlb-shm
+TEST_GEN_FILES += hugetlb-vmemmap
+TEST_GEN_FILES += hugetlb-mmap
TEST_GEN_FILES += khugepaged
TEST_GEN_FILES += madv_populate
TEST_GEN_FILES += map_fixed_noreplace
diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c
index 5b12041fa310..898cc90b314f 100644
--- a/tools/testing/selftests/mm/hugetlb-madvise.c
+++ b/tools/testing/selftests/mm/hugetlb-madvise.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * hugepage-madvise:
+ * hugetlb-madvise:
*
* Basic functional testing of madvise MADV_DONTNEED and MADV_REMOVE
* on hugetlb mappings.
diff --git a/tools/testing/selftests/mm/hugepage-mmap.c b/tools/testing/selftests/mm/hugetlb-mmap.c
similarity index 99%
rename from tools/testing/selftests/mm/hugepage-mmap.c
rename to tools/testing/selftests/mm/hugetlb-mmap.c
index de210043045a..71a444d8b1cb 100644
--- a/tools/testing/selftests/mm/hugepage-mmap.c
+++ b/tools/testing/selftests/mm/hugetlb-mmap.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * hugepage-mmap:
+ * hugetlb-mmap:
*
* Example of using huge page memory in a user application using the mmap
* system call. Before running this application, make sure that the
diff --git a/tools/testing/selftests/mm/hugepage-mremap.c b/tools/testing/selftests/mm/hugetlb-mremap.c
similarity index 99%
rename from tools/testing/selftests/mm/hugepage-mremap.c
rename to tools/testing/selftests/mm/hugetlb-mremap.c
index b8f7d92e5a35..1c87c39780c5 100644
--- a/tools/testing/selftests/mm/hugepage-mremap.c
+++ b/tools/testing/selftests/mm/hugetlb-mremap.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * hugepage-mremap:
+ * hugetlb-mremap:
*
* Example of remapping huge page memory in a user application using the
* mremap system call. The path to a file in a hugetlbfs filesystem must
diff --git a/tools/testing/selftests/mm/hugepage-shm.c b/tools/testing/selftests/mm/hugetlb-shm.c
similarity index 99%
rename from tools/testing/selftests/mm/hugepage-shm.c
rename to tools/testing/selftests/mm/hugetlb-shm.c
index ef06260802b5..de8f5d523084 100644
--- a/tools/testing/selftests/mm/hugepage-shm.c
+++ b/tools/testing/selftests/mm/hugetlb-shm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * hugepage-shm:
+ * hugetlb-shm:
*
* Example of using huge page memory in a user application using Sys V shared
* memory system calls. In this example the app is requesting 256MB of
diff --git a/tools/testing/selftests/mm/hugepage-vmemmap.c b/tools/testing/selftests/mm/hugetlb-vmemmap.c
similarity index 100%
rename from tools/testing/selftests/mm/hugepage-vmemmap.c
rename to tools/testing/selftests/mm/hugetlb-vmemmap.c
diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh
index 61b450032af8..b9e520194634 100755
--- a/tools/testing/selftests/mm/run_vmtests.sh
+++ b/tools/testing/selftests/mm/run_vmtests.sh
@@ -282,18 +282,18 @@ run_test() {
echo "TAP version 13" | tap_output
-CATEGORY="hugetlb" run_test ./hugepage-mmap
+CATEGORY="hugetlb" run_test ./hugetlb-mmap
shmmax=$(cat /proc/sys/kernel/shmmax)
shmall=$(cat /proc/sys/kernel/shmall)
echo 268435456 > /proc/sys/kernel/shmmax
echo 4194304 > /proc/sys/kernel/shmall
-CATEGORY="hugetlb" run_test ./hugepage-shm
+CATEGORY="hugetlb" run_test ./hugetlb-shm
echo "$shmmax" > /proc/sys/kernel/shmmax
echo "$shmall" > /proc/sys/kernel/shmall
-CATEGORY="hugetlb" run_test ./hugepage-mremap
-CATEGORY="hugetlb" run_test ./hugepage-vmemmap
+CATEGORY="hugetlb" run_test ./hugetlb-mremap
+CATEGORY="hugetlb" run_test ./hugetlb-vmemmap
CATEGORY="hugetlb" run_test ./hugetlb-madvise
CATEGORY="hugetlb" run_test ./hugetlb_dio
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 07/53] selftests/mm: hugetlb-shm: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (5 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 06/53] selftests/mm: rename hugepage-* tests to hugetlb-* Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:27 ` Mark Brown
2026-04-06 14:16 ` [PATCH 08/53] selftests/mm: hugetlb-vmemmap: " Mike Rapoport
` (45 subsequent siblings)
52 siblings, 1 reply; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert hugetlb-shm test to use kselftest framework for reporting and
tracking successful and failing runs.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb-shm.c | 46 ++++++++++++------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb-shm.c b/tools/testing/selftests/mm/hugetlb-shm.c
index de8f5d523084..10e4baa091f2 100644
--- a/tools/testing/selftests/mm/hugetlb-shm.c
+++ b/tools/testing/selftests/mm/hugetlb-shm.c
@@ -28,9 +28,9 @@
#include <sys/shm.h>
#include <sys/mman.h>
-#define LENGTH (256UL*1024*1024)
+#include "vm_util.h"
-#define dprintf(x) printf(x)
+#define LENGTH (256UL*1024*1024)
int main(void)
{
@@ -38,44 +38,44 @@ int main(void)
unsigned long i;
char *shmaddr;
+ ksft_print_header();
+ ksft_set_plan(1);
+
shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
- if (shmid < 0) {
- perror("shmget");
- exit(1);
- }
- printf("shmid: 0x%x\n", shmid);
+ if (shmid < 0)
+ ksft_exit_fail_perror("shmget");
+
+ ksft_print_msg("shmid: 0x%x\n", shmid);
shmaddr = shmat(shmid, NULL, 0);
if (shmaddr == (char *)-1) {
- perror("Shared memory attach failure");
+ ksft_perror("Shared memory attach failure");
shmctl(shmid, IPC_RMID, NULL);
- exit(2);
+ ksft_exit_fail();
}
- printf("shmaddr: %p\n", shmaddr);
+ ksft_print_msg("shmaddr: %p\n", shmaddr);
- dprintf("Starting the writes:\n");
- for (i = 0; i < LENGTH; i++) {
+ ksft_print_msg("Starting the writes:\n");
+ for (i = 0; i < LENGTH; i++)
shmaddr[i] = (char)(i);
- if (!(i % (1024 * 1024)))
- dprintf(".");
- }
- dprintf("\n");
- dprintf("Starting the Check...");
+ ksft_print_msg("Starting the Check...");
for (i = 0; i < LENGTH; i++)
if (shmaddr[i] != (char)i) {
- printf("\nIndex %lu mismatched\n", i);
- exit(3);
+ ksft_print_msg("Index %lu mismatched\n", i);
+ shmctl(shmid, IPC_RMID, NULL);
+ ksft_exit_fail_msg("Data mismatch at index %lu\n", i);
}
- dprintf("Done.\n");
+ ksft_print_msg("Done.\n");
if (shmdt((const void *)shmaddr) != 0) {
- perror("Detach failure");
+ ksft_perror("Detach failure");
shmctl(shmid, IPC_RMID, NULL);
- exit(4);
+ ksft_exit_fail();
}
shmctl(shmid, IPC_RMID, NULL);
- return 0;
+ ksft_test_result_pass("hugepage using SysV shmget/shmat\n");
+ ksft_finished();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 08/53] selftests/mm: hugetlb-vmemmap: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (6 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 07/53] selftests/mm: hugetlb-shm: use kselftest framework Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:40 ` Mark Brown
2026-04-06 14:16 ` [PATCH 09/53] selftests/mm: hugetlb-madvise: " Mike Rapoport
` (44 subsequent siblings)
52 siblings, 1 reply; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert hugetlb-vmemmap test to use kselftest framework for reporting
and tracking successful and failing runs.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb-vmemmap.c | 42 +++++++++-----------
1 file changed, 18 insertions(+), 24 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb-vmemmap.c b/tools/testing/selftests/mm/hugetlb-vmemmap.c
index df366a4d1b92..485a6978b40f 100644
--- a/tools/testing/selftests/mm/hugetlb-vmemmap.c
+++ b/tools/testing/selftests/mm/hugetlb-vmemmap.c
@@ -63,7 +63,7 @@ static int check_page_flags(unsigned long pfn)
read(fd, &pageflags, sizeof(pageflags));
if ((pageflags & HEAD_PAGE_FLAGS) != HEAD_PAGE_FLAGS) {
close(fd);
- printf("Head page flags (%lx) is invalid\n", pageflags);
+ ksft_print_msg("Head page flags (%lx) is invalid\n", pageflags);
return -1;
}
@@ -77,7 +77,7 @@ static int check_page_flags(unsigned long pfn)
if ((pageflags & TAIL_PAGE_FLAGS) != TAIL_PAGE_FLAGS ||
(pageflags & HEAD_PAGE_FLAGS) == HEAD_PAGE_FLAGS) {
close(fd);
- printf("Tail page flags (%lx) is invalid\n", pageflags);
+ ksft_print_msg("Tail page flags (%lx) is invalid\n", pageflags);
return -1;
}
}
@@ -91,44 +91,38 @@ int main(int argc, char **argv)
{
void *addr;
unsigned long pfn;
+ int ret;
+
+ ksft_print_header();
+ ksft_set_plan(1);
pagesize = psize();
maplength = default_huge_page_size();
- if (!maplength) {
- printf("Unable to determine huge page size\n");
- exit(1);
- }
+ if (!maplength)
+ ksft_exit_skip("Unable to determine huge page size\n");
addr = mmap(NULL, maplength, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
+ if (addr == MAP_FAILED)
+ ksft_exit_fail_perror("mmap");
/* Trigger allocation of HugeTLB page. */
write_bytes(addr, maplength);
pfn = virt_to_pfn(addr);
if (pfn == -1UL) {
+ ksft_perror("virt_to_pfn");
munmap(addr, maplength);
- perror("virt_to_pfn");
- exit(1);
+ ksft_exit_fail();
}
- printf("Returned address is %p whose pfn is %lx\n", addr, pfn);
+ ksft_print_msg("Returned address is %p whose pfn is %lx\n", addr, pfn);
- if (check_page_flags(pfn) < 0) {
- munmap(addr, maplength);
- perror("check_page_flags");
- exit(1);
- }
+ ret = check_page_flags(pfn);
- /* munmap() length of MAP_HUGETLB memory must be hugepage aligned */
- if (munmap(addr, maplength)) {
- perror("munmap");
- exit(1);
- }
+ if (munmap(addr, maplength))
+ ksft_exit_fail_perror("munmap");
- return 0;
+ ksft_test_result(!ret, "HugeTLB vmemmap page flags\n");
+ ksft_finished();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 09/53] selftests/mm: hugetlb-madvise: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (7 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 08/53] selftests/mm: hugetlb-vmemmap: " Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:16 ` [PATCH 10/53] selftests/mm: hugetlb_madv_vs_map: " Mike Rapoport
` (43 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert hugetlb-madvise test to use kselftest framework for reporting
and tracking successful and failing runs.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb-madvise.c | 204 ++++++++-----------
1 file changed, 82 insertions(+), 122 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c
index 898cc90b314f..4c6c346a3af5 100644
--- a/tools/testing/selftests/mm/hugetlb-madvise.c
+++ b/tools/testing/selftests/mm/hugetlb-madvise.c
@@ -26,12 +26,11 @@
#define validate_free_pages(exp_free) \
do { \
- int fhp = get_free_hugepages(); \
- if (fhp != (exp_free)) { \
- printf("Unexpected number of free huge " \
- "pages line %d\n", __LINE__); \
- exit(1); \
- } \
+ unsigned long fhp = get_free_hugepages(); \
+ if (fhp != (exp_free)) \
+ ksft_exit_fail_msg("Unexpected number of free " \
+ "huge pages %ld, expected %ld line %d\n", \
+ fhp, (exp_free), __LINE__); \
} while (0)
unsigned long huge_page_size;
@@ -57,28 +56,24 @@ int main(int argc, char **argv)
int fd;
int ret;
+ ksft_print_header();
+ ksft_set_plan(1);
+
huge_page_size = default_huge_page_size();
- if (!huge_page_size) {
- printf("Unable to determine huge page size, exiting!\n");
- exit(1);
- }
+ if (!huge_page_size)
+ ksft_exit_skip("Unable to determine huge page size\n");
+
base_page_size = sysconf(_SC_PAGE_SIZE);
- if (!huge_page_size) {
- printf("Unable to determine base page size, exiting!\n");
- exit(1);
- }
+ if (!base_page_size)
+ ksft_exit_fail_msg("Unable to determine base page size\n");
free_hugepages = get_free_hugepages();
- if (free_hugepages < MIN_FREE_PAGES) {
- printf("Not enough free huge pages to test, exiting!\n");
- exit(KSFT_SKIP);
- }
+ if (free_hugepages < MIN_FREE_PAGES)
+ ksft_exit_skip("Not enough free huge pages (have %lu, need %d)\n", free_hugepages, MIN_FREE_PAGES);
fd = memfd_create(argv[0], MFD_HUGETLB);
- if (fd < 0) {
- perror("memfd_create() failed");
- exit(1);
- }
+ if (fd < 0)
+ ksft_exit_fail_perror("memfd_create");
/*
* Test validity of MADV_DONTNEED addr and length arguments. mmap
@@ -90,16 +85,13 @@ int main(int argc, char **argv)
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
-1, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
+ if (addr == MAP_FAILED)
+ ksft_exit_fail_perror("mmap");
+
if (munmap(addr, huge_page_size) ||
munmap(addr + (NR_HUGE_PAGES + 1) * huge_page_size,
- huge_page_size)) {
- perror("munmap");
- exit(1);
- }
+ huge_page_size))
+ ksft_exit_fail_perror("munmap");
addr = addr + huge_page_size;
write_fault_pages(addr, NR_HUGE_PAGES);
@@ -108,20 +100,14 @@ int main(int argc, char **argv)
/* addr before mapping should fail */
ret = madvise(addr - base_page_size, NR_HUGE_PAGES * huge_page_size,
MADV_DONTNEED);
- if (!ret) {
- printf("Unexpected success of madvise call with invalid addr line %d\n",
- __LINE__);
- exit(1);
- }
+ if (!ret)
+ ksft_exit_fail_msg("madvise with invalid addr unexpectedly succeeded line %d\n", __LINE__);
/* addr + length after mapping should fail */
ret = madvise(addr, (NR_HUGE_PAGES * huge_page_size) + base_page_size,
MADV_DONTNEED);
- if (!ret) {
- printf("Unexpected success of madvise call with invalid length line %d\n",
- __LINE__);
- exit(1);
- }
+ if (!ret)
+ ksft_exit_fail_msg("madvise with invalid length unexpectedly succeeded line %d\n", __LINE__);
(void)munmap(addr, NR_HUGE_PAGES * huge_page_size);
@@ -132,10 +118,9 @@ int main(int argc, char **argv)
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
-1, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
+ if (addr == MAP_FAILED)
+ ksft_exit_fail_perror("mmap");
+
write_fault_pages(addr, NR_HUGE_PAGES);
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
@@ -143,19 +128,14 @@ int main(int argc, char **argv)
ret = madvise(addr + base_page_size,
NR_HUGE_PAGES * huge_page_size - base_page_size,
MADV_DONTNEED);
- if (!ret) {
- printf("Unexpected success of madvise call with unaligned start address %d\n",
- __LINE__);
- exit(1);
- }
+ if (!ret)
+ ksft_exit_fail_msg("madvise with unaligned start unexpectedly succeeded line %d\n", __LINE__);
/* addr + length should be aligned down to huge page size */
if (madvise(addr,
((NR_HUGE_PAGES - 1) * huge_page_size) + base_page_size,
- MADV_DONTNEED)) {
- perror("madvise");
- exit(1);
- }
+ MADV_DONTNEED))
+ ksft_exit_fail_perror("madvise");
/* should free all but last page in mapping */
validate_free_pages(free_hugepages - 1);
@@ -170,17 +150,14 @@ int main(int argc, char **argv)
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
-1, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
+ if (addr == MAP_FAILED)
+ ksft_exit_fail_perror("mmap");
+
write_fault_pages(addr, NR_HUGE_PAGES);
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
- if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
- perror("madvise");
- exit(1);
- }
+ if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
+ ksft_exit_fail_perror("madvise");
/* should free all pages in mapping */
validate_free_pages(free_hugepages);
@@ -190,29 +167,25 @@ int main(int argc, char **argv)
/*
* Test MADV_DONTNEED on private mapping of hugetlb file
*/
- if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) {
- perror("fallocate");
- exit(1);
- }
+ if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size))
+ ksft_exit_fail_perror("fallocate");
+
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
addr = mmap(NULL, NR_HUGE_PAGES * huge_page_size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
+ if (addr == MAP_FAILED)
+ ksft_exit_fail_perror("mmap");
/* read should not consume any pages */
read_fault_pages(addr, NR_HUGE_PAGES);
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
/* madvise should not free any pages */
- if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
- perror("madvise");
- exit(1);
- }
+ if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
+ ksft_exit_fail_perror("madvise");
+
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
/* writes should allocate private pages */
@@ -220,10 +193,9 @@ int main(int argc, char **argv)
validate_free_pages(free_hugepages - (2 * NR_HUGE_PAGES));
/* madvise should free private pages */
- if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
- perror("madvise");
- exit(1);
- }
+ if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
+ ksft_exit_fail_perror("madvise");
+
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
/* writes should allocate private pages */
@@ -238,10 +210,9 @@ int main(int argc, char **argv)
* implementation.
*/
if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
- 0, NR_HUGE_PAGES * huge_page_size)) {
- perror("fallocate");
- exit(1);
- }
+ 0, NR_HUGE_PAGES * huge_page_size))
+ ksft_exit_fail_perror("fallocate");
+
validate_free_pages(free_hugepages);
(void)munmap(addr, NR_HUGE_PAGES * huge_page_size);
@@ -249,29 +220,25 @@ int main(int argc, char **argv)
/*
* Test MADV_DONTNEED on shared mapping of hugetlb file
*/
- if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) {
- perror("fallocate");
- exit(1);
- }
+ if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size))
+ ksft_exit_fail_perror("fallocate");
+
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
addr = mmap(NULL, NR_HUGE_PAGES * huge_page_size,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
+ if (addr == MAP_FAILED)
+ ksft_exit_fail_perror("mmap");
/* write should not consume any pages */
write_fault_pages(addr, NR_HUGE_PAGES);
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
/* madvise should not free any pages */
- if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
- perror("madvise");
- exit(1);
- }
+ if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
+ ksft_exit_fail_perror("madvise");
+
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
/*
@@ -279,29 +246,25 @@ int main(int argc, char **argv)
*
* madvise is same as hole punch and should free all pages.
*/
- if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE)) {
- perror("madvise");
- exit(1);
- }
+ if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE))
+ ksft_exit_fail_perror("madvise");
+
validate_free_pages(free_hugepages);
(void)munmap(addr, NR_HUGE_PAGES * huge_page_size);
/*
* Test MADV_REMOVE on shared and private mapping of hugetlb file
*/
- if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) {
- perror("fallocate");
- exit(1);
- }
+ if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size))
+ ksft_exit_fail_perror("fallocate");
+
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
addr = mmap(NULL, NR_HUGE_PAGES * huge_page_size,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
- if (addr == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
+ if (addr == MAP_FAILED)
+ ksft_exit_fail_perror("mmap");
/* shared write should not consume any additional pages */
write_fault_pages(addr, NR_HUGE_PAGES);
@@ -310,10 +273,8 @@ int main(int argc, char **argv)
addr2 = mmap(NULL, NR_HUGE_PAGES * huge_page_size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
- if (addr2 == MAP_FAILED) {
- perror("mmap");
- exit(1);
- }
+ if (addr2 == MAP_FAILED)
+ ksft_exit_fail_perror("mmap");
/* private read should not consume any pages */
read_fault_pages(addr2, NR_HUGE_PAGES);
@@ -324,17 +285,15 @@ int main(int argc, char **argv)
validate_free_pages(free_hugepages - (2 * NR_HUGE_PAGES));
/* madvise of shared mapping should not free any pages */
- if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
- perror("madvise");
- exit(1);
- }
+ if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
+ ksft_exit_fail_perror("madvise");
+
validate_free_pages(free_hugepages - (2 * NR_HUGE_PAGES));
/* madvise of private mapping should free private pages */
- if (madvise(addr2, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
- perror("madvise");
- exit(1);
- }
+ if (madvise(addr2, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
+ ksft_exit_fail_perror("madvise");
+
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
/* private write should consume additional pages again */
@@ -346,15 +305,16 @@ int main(int argc, char **argv)
* not correct. private pages should not be freed, but this is
* expected. See comment associated with FALLOC_FL_PUNCH_HOLE call.
*/
- if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE)) {
- perror("madvise");
- exit(1);
- }
+ if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE))
+ ksft_exit_fail_perror("madvise");
+
validate_free_pages(free_hugepages);
(void)munmap(addr, NR_HUGE_PAGES * huge_page_size);
(void)munmap(addr2, NR_HUGE_PAGES * huge_page_size);
close(fd);
- return 0;
+
+ ksft_test_result_pass("MADV_DONTNEED and MADV_REMOVE on hugetlb\n");
+ ksft_finished();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 10/53] selftests/mm: hugetlb_madv_vs_map: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (8 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 09/53] selftests/mm: hugetlb-madvise: " Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 15:06 ` Mark Brown
2026-04-06 14:16 ` [PATCH 11/53] selftests/mm: hugetlb-read-hwpoison: " Mike Rapoport
` (42 subsequent siblings)
52 siblings, 1 reply; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert hugetlb_madv_vs_map test to use kselftest framework for
reporting and tracking successful and failing runs.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
.../testing/selftests/mm/hugetlb_madv_vs_map.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
index efd774b41389..c7105c6d319b 100644
--- a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
+++ b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
@@ -25,7 +25,6 @@
#include <unistd.h>
#include "vm_util.h"
-#include "kselftest.h"
#define INLOOP_ITER 100
@@ -86,12 +85,14 @@ int main(void)
*/
int max = 10;
+ ksft_print_header();
+ ksft_set_plan(1);
+
free_hugepages = get_free_hugepages();
- if (free_hugepages != 1) {
+ if (free_hugepages != 1)
ksft_exit_skip("This test needs one and only one page to execute. Got %lu\n",
free_hugepages);
- }
mmap_size = default_huge_page_size();
@@ -100,10 +101,8 @@ int main(void)
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
-1, 0);
- if ((unsigned long)huge_ptr == -1) {
- ksft_test_result_fail("Failed to allocate huge page\n");
- return KSFT_FAIL;
- }
+ if ((unsigned long)huge_ptr == -1)
+ ksft_exit_fail_msg("Failed to allocate huge page\n");
pthread_create(&thread1, NULL, madv, NULL);
pthread_create(&thread2, NULL, touch, NULL);
@@ -115,12 +114,13 @@ int main(void)
if (ret) {
ksft_test_result_fail("Unexpected huge page allocation\n");
- return KSFT_FAIL;
+ ksft_finished();
}
/* Unmap and restart */
munmap(huge_ptr, mmap_size);
}
- return KSFT_PASS;
+ ksft_test_result_pass("No unexpected huge page allocations\n");
+ ksft_finished();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 11/53] selftests/mm: hugetlb-read-hwpoison: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (9 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 10/53] selftests/mm: hugetlb_madv_vs_map: " Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 16:19 ` Mark Brown
2026-04-06 14:16 ` [PATCH 12/53] selftests/mm: khugepaged: group tests in an array Mike Rapoport
` (41 subsequent siblings)
52 siblings, 1 reply; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert hugetlb-read-hwpoison test to use kselftest framework for
reporting and tracking successful and failing runs.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
.../selftests/mm/hugetlb-read-hwpoison.c | 118 +++++++++---------
1 file changed, 57 insertions(+), 61 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb-read-hwpoison.c b/tools/testing/selftests/mm/hugetlb-read-hwpoison.c
index 6bbf15f78061..01cd5465e0f8 100644
--- a/tools/testing/selftests/mm/hugetlb-read-hwpoison.c
+++ b/tools/testing/selftests/mm/hugetlb-read-hwpoison.c
@@ -13,9 +13,7 @@
#include <signal.h>
#include "kselftest.h"
-
-#define PREFIX " ... "
-#define ERROR_PREFIX " !!! "
+#include "vm_util.h"
#define MAX_WRITE_READ_CHUNK_SIZE (getpagesize() * 16)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
@@ -26,17 +24,22 @@ enum test_status {
TEST_SKIPPED = 2,
};
-static char *status_to_str(enum test_status status)
+static void report_status(enum test_status status, const char *test_name,
+ size_t chunk_size)
{
switch (status) {
case TEST_PASSED:
- return "TEST_PASSED";
+ ksft_test_result_pass("%s chunk_size=0x%lx\n",
+ test_name, chunk_size);
+ break;
case TEST_FAILED:
- return "TEST_FAILED";
+ ksft_test_result_fail("%s chunk_size=0x%lx\n",
+ test_name, chunk_size);
+ break;
case TEST_SKIPPED:
- return "TEST_SKIPPED";
- default:
- return "TEST_???";
+ ksft_test_result_skip("%s chunk_size=0x%lx\n",
+ test_name, chunk_size);
+ break;
}
}
@@ -59,8 +62,8 @@ static bool verify_chunk(char *buf, size_t len, char val)
for (i = 0; i < len; ++i) {
if (buf[i] != val) {
- printf(PREFIX ERROR_PREFIX "check fail: buf[%lu] = %u != %u\n",
- i, buf[i], val);
+ ksft_print_msg("check fail: buf[%lu] = %u != %u\n",
+ i, buf[i], val);
return false;
}
}
@@ -76,21 +79,21 @@ static bool seek_read_hugepage_filemap(int fd, size_t len, size_t wr_chunk_size,
ssize_t total_ret_count = 0;
char val = offset / wr_chunk_size + offset % wr_chunk_size;
- printf(PREFIX PREFIX "init val=%u with offset=0x%lx\n", val, offset);
- printf(PREFIX PREFIX "expect to read 0x%lx bytes of data in total\n",
- expected);
+ ksft_print_msg("init val=%u with offset=0x%lx\n", val, offset);
+ ksft_print_msg("expect to read 0x%lx bytes of data in total\n",
+ expected);
if (lseek(fd, offset, SEEK_SET) < 0) {
- perror(PREFIX ERROR_PREFIX "seek failed");
+ ksft_perror("seek failed");
return false;
}
while (offset + total_ret_count < len) {
ret_count = read(fd, buf, wr_chunk_size);
if (ret_count == 0) {
- printf(PREFIX PREFIX "read reach end of the file\n");
+ ksft_print_msg("read reach end of the file\n");
break;
} else if (ret_count < 0) {
- perror(PREFIX ERROR_PREFIX "read failed");
+ ksft_perror("read failed");
break;
}
++val;
@@ -99,8 +102,8 @@ static bool seek_read_hugepage_filemap(int fd, size_t len, size_t wr_chunk_size,
total_ret_count += ret_count;
}
- printf(PREFIX PREFIX "actually read 0x%lx bytes of data in total\n",
- total_ret_count);
+ ksft_print_msg("actually read 0x%lx bytes of data in total\n",
+ total_ret_count);
return total_ret_count == expected;
}
@@ -113,15 +116,15 @@ static bool read_hugepage_filemap(int fd, size_t len,
ssize_t total_ret_count = 0;
char val = 0;
- printf(PREFIX PREFIX "expect to read 0x%lx bytes of data in total\n",
- expected);
+ ksft_print_msg("expect to read 0x%lx bytes of data in total\n",
+ expected);
while (total_ret_count < len) {
ret_count = read(fd, buf, wr_chunk_size);
if (ret_count == 0) {
- printf(PREFIX PREFIX "read reach end of the file\n");
+ ksft_print_msg("read reach end of the file\n");
break;
} else if (ret_count < 0) {
- perror(PREFIX ERROR_PREFIX "read failed");
+ ksft_perror("read failed");
break;
}
++val;
@@ -130,8 +133,8 @@ static bool read_hugepage_filemap(int fd, size_t len,
total_ret_count += ret_count;
}
- printf(PREFIX PREFIX "actually read 0x%lx bytes of data in total\n",
- total_ret_count);
+ ksft_print_msg("actually read 0x%lx bytes of data in total\n",
+ total_ret_count);
return total_ret_count == expected;
}
@@ -143,14 +146,14 @@ test_hugetlb_read(int fd, size_t len, size_t wr_chunk_size)
char *filemap = NULL;
if (ftruncate(fd, len) < 0) {
- perror(PREFIX ERROR_PREFIX "ftruncate failed");
+ ksft_perror("ftruncate failed");
return status;
}
filemap = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_POPULATE, fd, 0);
if (filemap == MAP_FAILED) {
- perror(PREFIX ERROR_PREFIX "mmap for primary mapping failed");
+ ksft_perror("mmap for primary mapping failed");
goto done;
}
@@ -163,7 +166,7 @@ test_hugetlb_read(int fd, size_t len, size_t wr_chunk_size)
munmap(filemap, len);
done:
if (ftruncate(fd, 0) < 0) {
- perror(PREFIX ERROR_PREFIX "ftruncate back to 0 failed");
+ ksft_perror("ftruncate back to 0 failed");
status = TEST_FAILED;
}
@@ -180,14 +183,14 @@ test_hugetlb_read_hwpoison(int fd, size_t len, size_t wr_chunk_size,
const unsigned long pagesize = getpagesize();
if (ftruncate(fd, len) < 0) {
- perror(PREFIX ERROR_PREFIX "ftruncate failed");
+ ksft_perror("ftruncate failed");
return status;
}
filemap = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_POPULATE, fd, 0);
if (filemap == MAP_FAILED) {
- perror(PREFIX ERROR_PREFIX "mmap for primary mapping failed");
+ ksft_perror("mmap for primary mapping failed");
goto done;
}
@@ -202,7 +205,7 @@ test_hugetlb_read_hwpoison(int fd, size_t len, size_t wr_chunk_size,
*/
hwp_addr = filemap + len / 2 + pagesize;
if (madvise(hwp_addr, pagesize, MADV_HWPOISON) < 0) {
- perror(PREFIX ERROR_PREFIX "MADV_HWPOISON failed");
+ ksft_perror("MADV_HWPOISON failed");
goto unmap;
}
@@ -229,7 +232,7 @@ test_hugetlb_read_hwpoison(int fd, size_t len, size_t wr_chunk_size,
munmap(filemap, len);
done:
if (ftruncate(fd, 0) < 0) {
- perror(PREFIX ERROR_PREFIX "ftruncate back to 0 failed");
+ ksft_perror("ftruncate back to 0 failed");
status = TEST_FAILED;
}
@@ -242,17 +245,17 @@ static int create_hugetlbfs_file(struct statfs *file_stat)
fd = memfd_create("hugetlb_tmp", MFD_HUGETLB);
if (fd < 0) {
- perror(PREFIX ERROR_PREFIX "could not open hugetlbfs file");
+ ksft_perror("could not open hugetlbfs file");
return -1;
}
memset(file_stat, 0, sizeof(*file_stat));
if (fstatfs(fd, file_stat)) {
- perror(PREFIX ERROR_PREFIX "fstatfs failed");
+ ksft_perror("fstatfs failed");
goto close;
}
if (file_stat->f_type != HUGETLBFS_MAGIC) {
- printf(PREFIX ERROR_PREFIX "not hugetlbfs file\n");
+ ksft_print_msg("not hugetlbfs file\n");
goto close;
}
@@ -264,7 +267,7 @@ static int create_hugetlbfs_file(struct statfs *file_stat)
static void sigbus_handler(int sig)
{
- printf(PREFIX "received SIGBUS\n");
+ ksft_print_msg("received SIGBUS\n");
}
int main(void)
@@ -279,51 +282,44 @@ int main(void)
};
size_t i;
+ ksft_print_header();
+ ksft_set_plan(ARRAY_SIZE(wr_chunk_sizes) * 3);
+
signal(SIGBUS, sigbus_handler);
for (i = 0; i < ARRAY_SIZE(wr_chunk_sizes); ++i) {
- printf("Write/read chunk size=0x%lx\n",
- wr_chunk_sizes[i]);
+ ksft_print_msg("Write/read chunk size=0x%lx\n",
+ wr_chunk_sizes[i]);
fd = create_hugetlbfs_file(&file_stat);
if (fd < 0)
- goto create_failure;
- printf(PREFIX "HugeTLB read regression test...\n");
+ ksft_exit_fail_msg("Failed to create hugetlbfs file\n");
+
status = test_hugetlb_read(fd, file_stat.f_bsize,
wr_chunk_sizes[i]);
- printf(PREFIX "HugeTLB read regression test...%s\n",
- status_to_str(status));
close(fd);
- if (status == TEST_FAILED)
- return -1;
+ report_status(status, "HugeTLB read regression",
+ wr_chunk_sizes[i]);
fd = create_hugetlbfs_file(&file_stat);
if (fd < 0)
- goto create_failure;
- printf(PREFIX "HugeTLB read HWPOISON test...\n");
+ ksft_exit_fail_msg("Failed to create hugetlbfs file\n");
+
status = test_hugetlb_read_hwpoison(fd, file_stat.f_bsize,
wr_chunk_sizes[i], false);
- printf(PREFIX "HugeTLB read HWPOISON test...%s\n",
- status_to_str(status));
close(fd);
- if (status == TEST_FAILED)
- return -1;
+ report_status(status, "HugeTLB read HWPOISON",
+ wr_chunk_sizes[i]);
fd = create_hugetlbfs_file(&file_stat);
if (fd < 0)
- goto create_failure;
- printf(PREFIX "HugeTLB seek then read HWPOISON test...\n");
+ ksft_exit_fail_msg("Failed to create hugetlbfs file\n");
+
status = test_hugetlb_read_hwpoison(fd, file_stat.f_bsize,
wr_chunk_sizes[i], true);
- printf(PREFIX "HugeTLB seek then read HWPOISON test...%s\n",
- status_to_str(status));
close(fd);
- if (status == TEST_FAILED)
- return -1;
+ report_status(status, "HugeTLB seek then read HWPOISON",
+ wr_chunk_sizes[i]);
}
- return 0;
-
-create_failure:
- printf(ERROR_PREFIX "Abort test: failed to create hugetlbfs file\n");
- return -1;
+ ksft_finished();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 12/53] selftests/mm: khugepaged: group tests in an array
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (10 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 11/53] selftests/mm: hugetlb-read-hwpoison: " Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 16:49 ` Mark Brown
2026-04-06 14:16 ` [PATCH 13/53] selftests/mm: khugepaged: use ksefltest framework Mike Rapoport
` (40 subsequent siblings)
52 siblings, 1 reply; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Currently khugepaged decides if a test can run using TEST() macro that
checks what mem_ops and collapse_context are set by the command line
arguments.
For better compatibility with ksefltest framework, add an array of 'struct
test_case's and redefine TEST() macro to conditionally add enabled tests to
that array.
Then execute the enabled test by looping the test_case's array.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/khugepaged.c | 43 +++++++++++++++++++++----
1 file changed, 36 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c
index e6fb01ca44ed..1cdc5918d20d 100644
--- a/tools/testing/selftests/mm/khugepaged.c
+++ b/tools/testing/selftests/mm/khugepaged.c
@@ -1161,6 +1161,34 @@ static void parse_test_type(int argc, char **argv)
get_finfo(argv[1]);
}
+typedef void (*test_fn)(struct collapse_context *c, struct mem_ops *ops);
+
+struct test_case {
+ struct collapse_context *ctx;
+ struct mem_ops *ops;
+ const char *desc;
+ test_fn fn;
+};
+
+#define MAX_TEST_CASES 45
+static struct test_case test_cases[MAX_TEST_CASES];
+static int nr_test_cases;
+
+#define TEST(t, c, o) do { \
+ if (c && o) { \
+ if (nr_test_cases >= MAX_TEST_CASES) { \
+ printf("MAX_ADD_CASES is too small\n"); \
+ exit(EXIT_FAILURE); \
+ } \
+ test_cases[nr_test_cases++] = (struct test_case){ \
+ .ctx = c, \
+ .ops = o, \
+ .desc = #t, \
+ .fn = t, \
+ }; \
+ } \
+ } while (0)
+
int main(int argc, char **argv)
{
int hpage_pmd_order;
@@ -1216,13 +1244,6 @@ int main(int argc, char **argv)
alloc_at_fault();
-#define TEST(t, c, o) do { \
- if (c && o) { \
- printf("\nRun test: " #t " (%s:%s)\n", c->name, o->name); \
- t(c, o); \
- } \
- } while (0)
-
TEST(collapse_full, khugepaged_context, anon_ops);
TEST(collapse_full, khugepaged_context, file_ops);
TEST(collapse_full, khugepaged_context, shmem_ops);
@@ -1284,5 +1305,13 @@ int main(int argc, char **argv)
TEST(madvise_retracted_page_tables, madvise_context, file_ops);
TEST(madvise_retracted_page_tables, madvise_context, shmem_ops);
+ for (int i = 0; i < nr_test_cases; i++) {
+ struct test_case *t = &test_cases[i];
+
+ exit_status = KSFT_PASS;
+ printf("\nRun test: %s: (%s:%s)\n", t->desc, t->ctx->name, t->ops->name);
+ t->fn(t->ctx, t->ops);
+ }
+
restore_settings(0);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 13/53] selftests/mm: khugepaged: use ksefltest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (11 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 12/53] selftests/mm: khugepaged: group tests in an array Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:16 ` [PATCH 14/53] selftests/mm: ksm_tests: use kselftest framework Mike Rapoport
` (39 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert khugepaged tests to use kselftest framework for reporting and
tracking successful and failing runs.
The conversion is mostly about replacing printf()/perror() + exit() pairs
with their ksft_ counterparts.
The nice colored success and failure indications are left intact.
Replace the progress report in collapse_compound_extreme() with a single
ksft_print_msg() to avoid headache with formatting and make the test output
more concise.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/khugepaged.c | 311 ++++++++++--------------
1 file changed, 128 insertions(+), 183 deletions(-)
diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c
index 1cdc5918d20d..ba0a9e14e600 100644
--- a/tools/testing/selftests/mm/khugepaged.c
+++ b/tools/testing/selftests/mm/khugepaged.c
@@ -83,12 +83,13 @@ static void success(const char *msg)
static void fail(const char *msg)
{
printf(" \e[31m%s\e[0m\n", msg);
- exit_status++;
+ exit_status = KSFT_FAIL;
}
static void skip(const char *msg)
{
printf(" \e[33m%s\e[0m\n", msg);
+ exit_status = KSFT_SKIP;
}
static void restore_settings_atexit(void)
@@ -96,22 +97,23 @@ static void restore_settings_atexit(void)
if (skip_settings_restore)
return;
- printf("Restore THP and khugepaged settings...");
+ ksft_print_msg("Restore THP and khugepaged settings...");
thp_restore_settings();
success("OK");
skip_settings_restore = true;
+ ksft_finished();
}
static void restore_settings(int sig)
{
/* exit() will invoke the restore_settings_atexit handler. */
- exit(sig ? EXIT_FAILURE : exit_status);
+ exit(sig ? KSFT_FAIL : exit_status);
}
static void save_settings(void)
{
- printf("Save THP and khugepaged settings...");
+ ksft_print_msg("Save THP and khugepaged settings...");
if (file_ops && finfo.type == VMA_FILE)
thp_set_read_ahead_path(finfo.dev_queue_read_ahead_path);
thp_save_settings();
@@ -135,19 +137,13 @@ static void get_finfo(const char *dir)
finfo.dir = dir;
stat(finfo.dir, &path_stat);
- if (!S_ISDIR(path_stat.st_mode)) {
- printf("%s: Not a directory (%s)\n", __func__, finfo.dir);
- exit(EXIT_FAILURE);
- }
+ if (!S_ISDIR(path_stat.st_mode))
+ ksft_exit_fail_msg("%s: Not a directory (%s)\n", __func__, finfo.dir);
if (snprintf(finfo.path, sizeof(finfo.path), "%s/" TEST_FILE,
- finfo.dir) >= sizeof(finfo.path)) {
- printf("%s: Pathname is too long\n", __func__);
- exit(EXIT_FAILURE);
- }
- if (statfs(finfo.dir, &fs)) {
- perror("statfs()");
- exit(EXIT_FAILURE);
- }
+ finfo.dir) >= sizeof(finfo.path))
+ ksft_exit_fail_msg("%s: Pathname is too long\n", __func__);
+ if (statfs(finfo.dir, &fs))
+ ksft_exit_fail_perror("statfs()");
finfo.type = fs.f_type == TMPFS_MAGIC ? VMA_SHMEM : VMA_FILE;
if (finfo.type == VMA_SHMEM)
return;
@@ -155,40 +151,30 @@ static void get_finfo(const char *dir)
/* Find owning device's queue/read_ahead_kb control */
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/uevent",
major(path_stat.st_dev), minor(path_stat.st_dev))
- >= sizeof(path)) {
- printf("%s: Pathname is too long\n", __func__);
- exit(EXIT_FAILURE);
- }
- if (read_file(path, buf, sizeof(buf)) < 0) {
- perror("read_file(read_num)");
- exit(EXIT_FAILURE);
- }
+ >= sizeof(path))
+ ksft_exit_fail_msg("%s: Pathname is too long\n", __func__);
+ if (read_file(path, buf, sizeof(buf)) < 0)
+ ksft_exit_fail_perror("read_file(read_num)");
if (strstr(buf, "DEVTYPE=disk")) {
/* Found it */
if (snprintf(finfo.dev_queue_read_ahead_path,
sizeof(finfo.dev_queue_read_ahead_path),
"/sys/dev/block/%d:%d/queue/read_ahead_kb",
major(path_stat.st_dev), minor(path_stat.st_dev))
- >= sizeof(finfo.dev_queue_read_ahead_path)) {
- printf("%s: Pathname is too long\n", __func__);
- exit(EXIT_FAILURE);
- }
+ >= sizeof(finfo.dev_queue_read_ahead_path))
+ ksft_exit_fail_msg("%s: Pathname is too long\n", __func__);
return;
}
- if (!strstr(buf, "DEVTYPE=partition")) {
- printf("%s: Unknown device type: %s\n", __func__, path);
- exit(EXIT_FAILURE);
- }
+ if (!strstr(buf, "DEVTYPE=partition"))
+ ksft_exit_fail_msg("%s: Unknown device type: %s\n", __func__, path);
/*
* Partition of block device - need to find actual device.
* Using naming convention that devnameN is partition of
* device devname.
*/
str = strstr(buf, "DEVNAME=");
- if (!str) {
- printf("%s: Could not read: %s", __func__, path);
- exit(EXIT_FAILURE);
- }
+ if (!str)
+ ksft_exit_fail_msg("%s: Could not read: %s", __func__, path);
str += 8;
end = str;
while (*end) {
@@ -197,16 +183,13 @@ static void get_finfo(const char *dir)
if (snprintf(finfo.dev_queue_read_ahead_path,
sizeof(finfo.dev_queue_read_ahead_path),
"/sys/block/%s/queue/read_ahead_kb",
- str) >= sizeof(finfo.dev_queue_read_ahead_path)) {
- printf("%s: Pathname is too long\n", __func__);
- exit(EXIT_FAILURE);
- }
+ str) >= sizeof(finfo.dev_queue_read_ahead_path))
+ ksft_exit_fail_msg("%s: Pathname is too long\n", __func__);
return;
}
++end;
}
- printf("%s: Could not read: %s\n", __func__, path);
- exit(EXIT_FAILURE);
+ ksft_exit_fail_msg("%s: Could not read: %s\n", __func__, path);
}
static bool check_swap(void *addr, unsigned long size)
@@ -219,26 +202,19 @@ static bool check_swap(void *addr, unsigned long size)
ret = snprintf(addr_pattern, MAX_LINE_LENGTH, "%08lx-",
(unsigned long) addr);
- if (ret >= MAX_LINE_LENGTH) {
- printf("%s: Pattern is too long\n", __func__);
- exit(EXIT_FAILURE);
- }
-
+ if (ret >= MAX_LINE_LENGTH)
+ ksft_exit_fail_msg("%s: Pattern is too long\n", __func__);
fp = fopen(PID_SMAPS, "r");
- if (!fp) {
- printf("%s: Failed to open file %s\n", __func__, PID_SMAPS);
- exit(EXIT_FAILURE);
- }
+ if (!fp)
+ ksft_exit_fail_msg("%s: Failed to open file %s\n", __func__, PID_SMAPS);
if (!check_for_pattern(fp, addr_pattern, buffer, sizeof(buffer)))
goto err_out;
ret = snprintf(addr_pattern, MAX_LINE_LENGTH, "Swap:%19ld kB",
size >> 10);
- if (ret >= MAX_LINE_LENGTH) {
- printf("%s: Pattern is too long\n", __func__);
- exit(EXIT_FAILURE);
- }
+ if (ret >= MAX_LINE_LENGTH)
+ ksft_exit_fail_msg("%s: Pattern is too long\n", __func__);
/*
* Fetch the Swap: in the same block and check whether it got
* the expected number of hugeepages next.
@@ -261,10 +237,8 @@ static void *alloc_mapping(int nr)
p = mmap(BASE_ADDR, nr * hpage_pmd_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- if (p != BASE_ADDR) {
- printf("Failed to allocate VMA at %p\n", BASE_ADDR);
- exit(EXIT_FAILURE);
- }
+ if (p != BASE_ADDR)
+ ksft_exit_fail_msg("Failed to allocate VMA at %p\n", BASE_ADDR);
return p;
}
@@ -314,19 +288,13 @@ static void *alloc_hpage(struct mem_ops *ops)
* khugepaged on low-load system (like a test machine), which
* would cause MADV_COLLAPSE to fail with EAGAIN.
*/
- printf("Allocate huge page...");
- if (madvise_collapse_retry(p, hpage_pmd_size)) {
- perror("madvise(MADV_COLLAPSE)");
- exit(EXIT_FAILURE);
- }
- if (!ops->check_huge(p, 1)) {
- perror("madvise(MADV_COLLAPSE)");
- exit(EXIT_FAILURE);
- }
- if (madvise(p, hpage_pmd_size, MADV_HUGEPAGE)) {
- perror("madvise(MADV_HUGEPAGE)");
- exit(EXIT_FAILURE);
- }
+ ksft_print_msg("Allocate huge page...");
+ if (madvise_collapse_retry(p, hpage_pmd_size))
+ ksft_exit_fail_perror("madvise(MADV_COLLAPSE)");
+ if (!ops->check_huge(p, 1))
+ ksft_exit_fail_perror("madvise(MADV_COLLAPSE)");
+ if (madvise(p, hpage_pmd_size, MADV_HUGEPAGE))
+ ksft_exit_fail_perror("madvise(MADV_HUGEPAGE)");
success("OK");
return p;
}
@@ -336,11 +304,9 @@ static void validate_memory(int *p, unsigned long start, unsigned long end)
int i;
for (i = start / page_size; i < end / page_size; i++) {
- if (p[i * page_size / sizeof(*p)] != i + 0xdead0000) {
- printf("Page %d is corrupted: %#x\n",
- i, p[i * page_size / sizeof(*p)]);
- exit(EXIT_FAILURE);
- }
+ if (p[i * page_size / sizeof(*p)] != i + 0xdead0000)
+ ksft_exit_fail_msg("Page %d is corrupted: %#x\n",
+ i, p[i * page_size / sizeof(*p)]);
}
}
@@ -371,14 +337,12 @@ static void *file_setup_area(int nr_hpages)
unsigned long size;
unlink(finfo.path); /* Cleanup from previous failed tests */
- printf("Creating %s for collapse%s...", finfo.path,
- finfo.type == VMA_SHMEM ? " (tmpfs)" : "");
+ ksft_print_msg("Creating %s for collapse%s...", finfo.path,
+ finfo.type == VMA_SHMEM ? " (tmpfs)" : "");
fd = open(finfo.path, O_DSYNC | O_CREAT | O_RDWR | O_TRUNC | O_EXCL,
777);
- if (fd < 0) {
- perror("open()");
- exit(EXIT_FAILURE);
- }
+ if (fd < 0)
+ ksft_exit_fail_perror("open()");
size = nr_hpages * hpage_pmd_size;
p = alloc_mapping(nr_hpages);
@@ -388,18 +352,14 @@ static void *file_setup_area(int nr_hpages)
munmap(p, size);
success("OK");
- printf("Opening %s read only for collapse...", finfo.path);
+ ksft_print_msg("Opening %s read only for collapse...", finfo.path);
finfo.fd = open(finfo.path, O_RDONLY, 777);
- if (finfo.fd < 0) {
- perror("open()");
- exit(EXIT_FAILURE);
- }
+ if (finfo.fd < 0)
+ ksft_exit_fail_perror("open()");
p = mmap(BASE_ADDR, size, PROT_READ,
MAP_PRIVATE, finfo.fd, 0);
- if (p == MAP_FAILED || p != BASE_ADDR) {
- perror("mmap()");
- exit(EXIT_FAILURE);
- }
+ if (p == MAP_FAILED || p != BASE_ADDR)
+ ksft_exit_fail_perror("mmap()");
/* Drop page cache */
write_file("/proc/sys/vm/drop_caches", "3", 2);
@@ -416,10 +376,8 @@ static void file_cleanup_area(void *p, unsigned long size)
static void file_fault(void *p, unsigned long start, unsigned long end)
{
- if (madvise(((char *)p) + start, end - start, MADV_POPULATE_READ)) {
- perror("madvise(MADV_POPULATE_READ");
- exit(EXIT_FAILURE);
- }
+ if (madvise(((char *)p) + start, end - start, MADV_POPULATE_READ))
+ ksft_exit_fail_perror("madvise(MADV_POPULATE_READ");
}
static bool file_check_huge(void *addr, int nr_hpages)
@@ -441,20 +399,14 @@ static void *shmem_setup_area(int nr_hpages)
unsigned long size = nr_hpages * hpage_pmd_size;
finfo.fd = memfd_create("khugepaged-selftest-collapse-shmem", 0);
- if (finfo.fd < 0) {
- perror("memfd_create()");
- exit(EXIT_FAILURE);
- }
- if (ftruncate(finfo.fd, size)) {
- perror("ftruncate()");
- exit(EXIT_FAILURE);
- }
+ if (finfo.fd < 0)
+ ksft_exit_fail_perror("memfd_create()");
+ if (ftruncate(finfo.fd, size))
+ ksft_exit_fail_perror("ftruncate()");
p = mmap(BASE_ADDR, size, PROT_READ | PROT_WRITE, MAP_SHARED, finfo.fd,
0);
- if (p != BASE_ADDR) {
- perror("mmap()");
- exit(EXIT_FAILURE);
- }
+ if (p != BASE_ADDR)
+ ksft_exit_fail_perror("mmap()");
return p;
}
@@ -499,7 +451,7 @@ static void __madvise_collapse(const char *msg, char *p, int nr_hpages,
int ret;
struct thp_settings settings = *thp_current_settings();
- printf("%s...", msg);
+ ksft_print_msg("%s...", msg);
/*
* Prevent khugepaged interference and tests that MADV_COLLAPSE
@@ -526,10 +478,8 @@ static void madvise_collapse(const char *msg, char *p, int nr_hpages,
struct mem_ops *ops, bool expect)
{
/* Sanity check */
- if (!ops->check_huge(p, 0)) {
- printf("Unexpected huge page\n");
- exit(EXIT_FAILURE);
- }
+ if (!ops->check_huge(p, 0))
+ ksft_exit_fail_msg("Unexpected huge page\n");
__madvise_collapse(msg, p, nr_hpages, ops, expect);
}
@@ -541,17 +491,15 @@ static bool wait_for_scan(const char *msg, char *p, int nr_hpages,
int timeout = 6; /* 3 seconds */
/* Sanity check */
- if (!ops->check_huge(p, 0)) {
- printf("Unexpected huge page\n");
- exit(EXIT_FAILURE);
- }
+ if (!ops->check_huge(p, 0))
+ ksft_exit_fail_msg("Unexpected huge page\n");
madvise(p, nr_hpages * hpage_pmd_size, MADV_HUGEPAGE);
/* Wait until the second full_scan completed */
full_scans = thp_read_num("khugepaged/full_scans") + 2;
- printf("%s...", msg);
+ ksft_print_msg("%s...", msg);
while (timeout--) {
if (ops->check_huge(p, nr_hpages))
break;
@@ -621,7 +569,7 @@ static void alloc_at_fault(void)
p = alloc_mapping(1);
*p = 1;
- printf("Allocate huge page on fault...");
+ ksft_print_msg("Allocate huge page on fault...");
if (check_huge_anon(p, 1, hpage_pmd_size))
success("OK");
else
@@ -630,12 +578,14 @@ static void alloc_at_fault(void)
thp_pop_settings();
madvise(p, page_size, MADV_DONTNEED);
- printf("Split huge PMD on MADV_DONTNEED...");
+ ksft_print_msg("Split huge PMD on MADV_DONTNEED...");
if (check_huge_anon(p, 0, hpage_pmd_size))
success("OK");
else
fail("Fail");
munmap(p, hpage_pmd_size);
+
+ ksft_test_result_report(exit_status, "allocate on fault and split\n");
}
static void collapse_full(struct collapse_context *c, struct mem_ops *ops)
@@ -650,6 +600,8 @@ static void collapse_full(struct collapse_context *c, struct mem_ops *ops)
ops, true);
validate_memory(p, 0, size);
ops->cleanup_area(p, size);
+
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_empty(struct collapse_context *c, struct mem_ops *ops)
@@ -659,6 +611,7 @@ static void collapse_empty(struct collapse_context *c, struct mem_ops *ops)
p = ops->setup_area(1);
c->collapse("Do not collapse empty PTE table", p, 1, ops, false);
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_single_pte_entry(struct collapse_context *c, struct mem_ops *ops)
@@ -670,6 +623,7 @@ static void collapse_single_pte_entry(struct collapse_context *c, struct mem_ops
c->collapse("Collapse PTE table with single PTE entry present", p,
1, ops, true);
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_max_ptes_none(struct collapse_context *c, struct mem_ops *ops)
@@ -706,6 +660,7 @@ static void collapse_max_ptes_none(struct collapse_context *c, struct mem_ops *o
skip:
ops->cleanup_area(p, hpage_pmd_size);
thp_pop_settings();
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_swapin_single_pte(struct collapse_context *c, struct mem_ops *ops)
@@ -715,11 +670,9 @@ static void collapse_swapin_single_pte(struct collapse_context *c, struct mem_op
p = ops->setup_area(1);
ops->fault(p, 0, hpage_pmd_size);
- printf("Swapout one page...");
- if (madvise(p, page_size, MADV_PAGEOUT)) {
- perror("madvise(MADV_PAGEOUT)");
- exit(EXIT_FAILURE);
- }
+ ksft_print_msg("Swapout one page...");
+ if (madvise(p, page_size, MADV_PAGEOUT))
+ ksft_exit_fail_perror("madvise(MADV_PAGEOUT)");
if (check_swap(p, page_size)) {
success("OK");
} else {
@@ -732,6 +685,7 @@ static void collapse_swapin_single_pte(struct collapse_context *c, struct mem_op
validate_memory(p, 0, hpage_pmd_size);
out:
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_max_ptes_swap(struct collapse_context *c, struct mem_ops *ops)
@@ -742,11 +696,9 @@ static void collapse_max_ptes_swap(struct collapse_context *c, struct mem_ops *o
p = ops->setup_area(1);
ops->fault(p, 0, hpage_pmd_size);
- printf("Swapout %d of %d pages...", max_ptes_swap + 1, hpage_pmd_nr);
- if (madvise(p, (max_ptes_swap + 1) * page_size, MADV_PAGEOUT)) {
- perror("madvise(MADV_PAGEOUT)");
- exit(EXIT_FAILURE);
- }
+ ksft_print_msg("Swapout %d of %d pages...", max_ptes_swap + 1, hpage_pmd_nr);
+ if (madvise(p, (max_ptes_swap + 1) * page_size, MADV_PAGEOUT))
+ ksft_exit_fail_perror("madvise(MADV_PAGEOUT)");
if (check_swap(p, (max_ptes_swap + 1) * page_size)) {
success("OK");
} else {
@@ -760,12 +712,10 @@ static void collapse_max_ptes_swap(struct collapse_context *c, struct mem_ops *o
if (c->enforce_pte_scan_limits) {
ops->fault(p, 0, hpage_pmd_size);
- printf("Swapout %d of %d pages...", max_ptes_swap,
+ ksft_print_msg("Swapout %d of %d pages...", max_ptes_swap,
hpage_pmd_nr);
- if (madvise(p, max_ptes_swap * page_size, MADV_PAGEOUT)) {
- perror("madvise(MADV_PAGEOUT)");
- exit(EXIT_FAILURE);
- }
+ if (madvise(p, max_ptes_swap * page_size, MADV_PAGEOUT))
+ ksft_exit_fail_perror("madvise(MADV_PAGEOUT)");
if (check_swap(p, max_ptes_swap * page_size)) {
success("OK");
} else {
@@ -779,6 +729,7 @@ static void collapse_max_ptes_swap(struct collapse_context *c, struct mem_ops *o
}
out:
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_single_pte_entry_compound(struct collapse_context *c, struct mem_ops *ops)
@@ -792,7 +743,7 @@ static void collapse_single_pte_entry_compound(struct collapse_context *c, struc
advise = MADV_REMOVE;
madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);
- printf("Split huge page leaving single PTE mapping compound page...");
+ ksft_print_msg("Split huge page leaving single PTE mapping compound page...");
madvise(p + page_size, hpage_pmd_size - page_size, advise);
if (ops->check_huge(p, 0))
success("OK");
@@ -803,6 +754,7 @@ static void collapse_single_pte_entry_compound(struct collapse_context *c, struc
p, 1, ops, true);
validate_memory(p, 0, page_size);
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_full_of_compound(struct collapse_context *c, struct mem_ops *ops)
@@ -810,7 +762,7 @@ static void collapse_full_of_compound(struct collapse_context *c, struct mem_ops
void *p;
p = alloc_hpage(ops);
- printf("Split huge page leaving single PTE page table full of compound pages...");
+ ksft_print_msg("Split huge page leaving single PTE page table full of compound pages...");
madvise(p, page_size, MADV_NOHUGEPAGE);
madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);
if (ops->check_huge(p, 0))
@@ -822,6 +774,7 @@ static void collapse_full_of_compound(struct collapse_context *c, struct mem_ops
true);
validate_memory(p, 0, hpage_pmd_size);
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops *ops)
@@ -830,16 +783,12 @@ static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops
int i;
p = ops->setup_area(1);
+ ksft_print_msg("Construct PTE page table full of different PTE-mapped compound pagesd\n");
for (i = 0; i < hpage_pmd_nr; i++) {
- printf("\rConstruct PTE page table full of different PTE-mapped compound pages %3d/%d...",
- i + 1, hpage_pmd_nr);
-
madvise(BASE_ADDR, hpage_pmd_size, MADV_HUGEPAGE);
ops->fault(BASE_ADDR, 0, hpage_pmd_size);
- if (!ops->check_huge(BASE_ADDR, 1)) {
- printf("Failed to allocate huge page\n");
- exit(EXIT_FAILURE);
- }
+ if (!ops->check_huge(BASE_ADDR, 1))
+ ksft_exit_fail_msg("Failed to allocate huge page\n");
madvise(BASE_ADDR, hpage_pmd_size, MADV_NOHUGEPAGE);
p = mremap(BASE_ADDR - i * page_size,
@@ -847,20 +796,16 @@ static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops
(i + 1) * page_size,
MREMAP_MAYMOVE | MREMAP_FIXED,
BASE_ADDR + 2 * hpage_pmd_size);
- if (p == MAP_FAILED) {
- perror("mremap+unmap");
- exit(EXIT_FAILURE);
- }
+ if (p == MAP_FAILED)
+ ksft_exit_fail_perror("mremap+unmap");
p = mremap(BASE_ADDR + 2 * hpage_pmd_size,
(i + 1) * page_size,
(i + 1) * page_size + hpage_pmd_size,
MREMAP_MAYMOVE | MREMAP_FIXED,
BASE_ADDR - (i + 1) * page_size);
- if (p == MAP_FAILED) {
- perror("mremap+alloc");
- exit(EXIT_FAILURE);
- }
+ if (p == MAP_FAILED)
+ ksft_exit_fail_perror("mremap+alloc");
}
ops->cleanup_area(BASE_ADDR, hpage_pmd_size);
@@ -875,6 +820,7 @@ static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops
validate_memory(p, 0, hpage_pmd_size);
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_fork(struct collapse_context *c, struct mem_ops *ops)
@@ -884,18 +830,17 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops)
p = ops->setup_area(1);
- printf("Allocate small page...");
+ ksft_print_msg("Allocate small page...");
ops->fault(p, 0, page_size);
if (ops->check_huge(p, 0))
success("OK");
else
fail("Fail");
- printf("Share small page over fork()...");
+ ksft_print_msg("Share small page over fork()...");
if (!fork()) {
/* Do not touch settings on child exit */
skip_settings_restore = true;
- exit_status = 0;
if (ops->check_huge(p, 0))
success("OK");
@@ -912,15 +857,16 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops)
}
wait(&wstatus);
- exit_status += WEXITSTATUS(wstatus);
+ exit_status = WEXITSTATUS(wstatus);
- printf("Check if parent still has small page...");
+ ksft_print_msg("Check if parent still has small page...");
if (ops->check_huge(p, 0))
success("OK");
else
fail("Fail");
validate_memory(p, 0, page_size);
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *ops)
@@ -929,18 +875,17 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o
void *p;
p = alloc_hpage(ops);
- printf("Share huge page over fork()...");
+ ksft_print_msg("Share huge page over fork()...");
if (!fork()) {
/* Do not touch settings on child exit */
skip_settings_restore = true;
- exit_status = 0;
if (ops->check_huge(p, 1))
success("OK");
else
fail("Fail");
- printf("Split huge page PMD in child process...");
+ ksft_print_msg("Split huge page PMD in child process...");
madvise(p, page_size, MADV_NOHUGEPAGE);
madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);
if (ops->check_huge(p, 0))
@@ -961,15 +906,16 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o
}
wait(&wstatus);
- exit_status += WEXITSTATUS(wstatus);
+ exit_status = WEXITSTATUS(wstatus);
- printf("Check if parent still has huge page...");
+ ksft_print_msg("Check if parent still has huge page...");
if (ops->check_huge(p, 1))
success("OK");
else
fail("Fail");
validate_memory(p, 0, hpage_pmd_size);
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops *ops)
@@ -979,18 +925,17 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops
void *p;
p = alloc_hpage(ops);
- printf("Share huge page over fork()...");
+ ksft_print_msg("Share huge page over fork()...");
if (!fork()) {
/* Do not touch settings on child exit */
skip_settings_restore = true;
- exit_status = 0;
if (ops->check_huge(p, 1))
success("OK");
else
fail("Fail");
- printf("Trigger CoW on page %d of %d...",
+ ksft_print_msg("Trigger CoW on page %d of %d...",
hpage_pmd_nr - max_ptes_shared - 1, hpage_pmd_nr);
ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared - 1) * page_size);
if (ops->check_huge(p, 0))
@@ -1002,7 +947,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops
1, ops, !c->enforce_pte_scan_limits);
if (c->enforce_pte_scan_limits) {
- printf("Trigger CoW on page %d of %d...",
+ ksft_print_msg("Trigger CoW on page %d of %d...",
hpage_pmd_nr - max_ptes_shared, hpage_pmd_nr);
ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared) *
page_size);
@@ -1021,15 +966,16 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops
}
wait(&wstatus);
- exit_status += WEXITSTATUS(wstatus);
+ exit_status = WEXITSTATUS(wstatus);
- printf("Check if parent still has huge page...");
+ ksft_print_msg("Check if parent still has huge page...");
if (ops->check_huge(p, 1))
success("OK");
else
fail("Fail");
validate_memory(p, 0, hpage_pmd_size);
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void madvise_collapse_existing_thps(struct collapse_context *c,
@@ -1046,6 +992,7 @@ static void madvise_collapse_existing_thps(struct collapse_context *c,
__madvise_collapse("Re-collapse PMD-mapped hugepage", p, 1, ops, true);
validate_memory(p, 0, hpage_pmd_size);
ops->cleanup_area(p, hpage_pmd_size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
/*
@@ -1073,6 +1020,7 @@ static void madvise_retracted_page_tables(struct collapse_context *c,
true);
validate_memory(p, 0, size);
ops->cleanup_area(p, size);
+ ksft_test_result_report(exit_status, "%s\n", __func__);
}
static void usage(void)
@@ -1176,10 +1124,8 @@ static int nr_test_cases;
#define TEST(t, c, o) do { \
if (c && o) { \
- if (nr_test_cases >= MAX_TEST_CASES) { \
- printf("MAX_ADD_CASES is too small\n"); \
- exit(EXIT_FAILURE); \
- } \
+ if (nr_test_cases >= MAX_TEST_CASES) \
+ ksft_exit_fail_msg("MAX_ADD_CASES is too small\n"); \
test_cases[nr_test_cases++] = (struct test_case){ \
.ctx = c, \
.ops = o, \
@@ -1212,10 +1158,10 @@ int main(int argc, char **argv)
.read_ahead_kb = 0,
};
- if (!thp_is_enabled()) {
- printf("Transparent Hugepages not available\n");
- return KSFT_SKIP;
- }
+ ksft_print_header();
+
+ if (!thp_is_enabled())
+ ksft_exit_skip("Transparent Hugepages not available\n");
parse_test_type(argc, argv);
@@ -1223,10 +1169,8 @@ int main(int argc, char **argv)
page_size = getpagesize();
hpage_pmd_size = read_pmd_pagesize();
- if (!hpage_pmd_size) {
- printf("Reading PMD pagesize failed");
- exit(EXIT_FAILURE);
- }
+ if (!hpage_pmd_size)
+ ksft_exit_fail_msg("Reading PMD pagesize failed\n");
hpage_pmd_nr = hpage_pmd_size / page_size;
hpage_pmd_order = __builtin_ctz(hpage_pmd_nr);
@@ -1242,8 +1186,6 @@ int main(int argc, char **argv)
save_settings();
thp_push_settings(&default_settings);
- alloc_at_fault();
-
TEST(collapse_full, khugepaged_context, anon_ops);
TEST(collapse_full, khugepaged_context, file_ops);
TEST(collapse_full, khugepaged_context, shmem_ops);
@@ -1305,11 +1247,14 @@ int main(int argc, char **argv)
TEST(madvise_retracted_page_tables, madvise_context, file_ops);
TEST(madvise_retracted_page_tables, madvise_context, shmem_ops);
+ ksft_set_plan(nr_test_cases + 1);
+
+ alloc_at_fault();
for (int i = 0; i < nr_test_cases; i++) {
struct test_case *t = &test_cases[i];
exit_status = KSFT_PASS;
- printf("\nRun test: %s: (%s:%s)\n", t->desc, t->ctx->name, t->ops->name);
+ ksft_print_msg("\nRun test: %s: (%s:%s)\n", t->desc, t->ctx->name, t->ops->name);
t->fn(t->ctx, t->ops);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 14/53] selftests/mm: ksm_tests: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (12 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 13/53] selftests/mm: khugepaged: use ksefltest framework Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:16 ` [PATCH 15/53] selftests/mm: protection_keys: use descriptive test names in TAP output Mike Rapoport
` (38 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert ksm_tests to use kselftest framework for reporting and tracking
successful and failing runs.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/ksm_tests.c | 180 +++++++++++--------------
1 file changed, 81 insertions(+), 99 deletions(-)
diff --git a/tools/testing/selftests/mm/ksm_tests.c b/tools/testing/selftests/mm/ksm_tests.c
index a0b48b839d54..752a2c0d06ab 100644
--- a/tools/testing/selftests/mm/ksm_tests.c
+++ b/tools/testing/selftests/mm/ksm_tests.c
@@ -175,12 +175,12 @@ static void *allocate_memory(void *ptr, int prot, int mapping, char data, size_
void *map_ptr = mmap(ptr, map_size, PROT_WRITE, mapping, -1, 0);
if (!map_ptr) {
- perror("mmap");
+ ksft_perror("mmap");
return NULL;
}
memset(map_ptr, data, map_size);
if (mprotect(map_ptr, map_size, prot)) {
- perror("mprotect");
+ ksft_perror("mprotect");
munmap(map_ptr, map_size);
return NULL;
}
@@ -201,11 +201,11 @@ static int ksm_do_scan(int scan_count, struct timespec start_time, int timeout)
if (ksm_read_sysfs(KSM_FP("full_scans"), &cur_scan))
return 1;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &cur_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
return 1;
}
if ((cur_time.tv_sec - start_time.tv_sec) > timeout) {
- printf("Scan time limit exceeded\n");
+ ksft_print_msg("Scan time limit exceeded\n");
return 1;
}
}
@@ -218,12 +218,12 @@ static int ksm_merge_pages(int merge_type, void *addr, size_t size,
{
if (merge_type == KSM_MERGE_MADVISE) {
if (madvise(addr, size, MADV_MERGEABLE)) {
- perror("madvise");
+ ksft_perror("madvise");
return 1;
}
} else if (merge_type == KSM_MERGE_PRCTL) {
if (prctl(PR_SET_MEMORY_MERGE, 1, 0, 0, 0)) {
- perror("prctl");
+ ksft_perror("prctl");
return 1;
}
}
@@ -242,7 +242,7 @@ static int ksm_unmerge_pages(void *addr, size_t size,
struct timespec start_time, int timeout)
{
if (madvise(addr, size, MADV_UNMERGEABLE)) {
- perror("madvise");
+ ksft_perror("madvise");
return 1;
}
return 0;
@@ -324,7 +324,7 @@ static int check_ksm_merge(int merge_type, int mapping, int prot,
struct timespec start_time;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
return KSFT_FAIL;
}
@@ -338,7 +338,6 @@ static int check_ksm_merge(int merge_type, int mapping, int prot,
/* verify that the right number of pages are merged */
if (assert_ksm_pages_count(page_count)) {
- printf("OK\n");
munmap(map_ptr, page_size * page_count);
if (merge_type == KSM_MERGE_PRCTL)
prctl(PR_SET_MEMORY_MERGE, 0, 0, 0, 0);
@@ -346,7 +345,6 @@ static int check_ksm_merge(int merge_type, int mapping, int prot,
}
err_out:
- printf("Not OK\n");
munmap(map_ptr, page_size * page_count);
return KSFT_FAIL;
}
@@ -358,7 +356,7 @@ static int check_ksm_unmerge(int merge_type, int mapping, int prot, int timeout,
int page_count = 2;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
return KSFT_FAIL;
}
@@ -380,13 +378,11 @@ static int check_ksm_unmerge(int merge_type, int mapping, int prot, int timeout,
/* check that unmerging was successful and 0 pages are currently merged */
if (assert_ksm_pages_count(0)) {
- printf("OK\n");
munmap(map_ptr, page_size * page_count);
return KSFT_PASS;
}
err_out:
- printf("Not OK\n");
munmap(map_ptr, page_size * page_count);
return KSFT_FAIL;
}
@@ -398,7 +394,7 @@ static int check_ksm_zero_page_merge(int merge_type, int mapping, int prot, long
struct timespec start_time;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
return KSFT_FAIL;
}
@@ -425,12 +421,10 @@ static int check_ksm_zero_page_merge(int merge_type, int mapping, int prot, long
else if (!use_zero_pages && !assert_ksm_pages_count(page_count))
goto err_out;
- printf("OK\n");
munmap(map_ptr, page_size * page_count);
return KSFT_PASS;
err_out:
- printf("Not OK\n");
munmap(map_ptr, page_size * page_count);
return KSFT_FAIL;
}
@@ -465,16 +459,16 @@ static int check_ksm_numa_merge(int merge_type, int mapping, int prot, int timeo
int first_node;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
return KSFT_FAIL;
}
if (numa_available() < 0) {
- perror("NUMA support not enabled");
+ ksft_perror("NUMA support not enabled");
return KSFT_SKIP;
}
if (numa_num_configured_nodes() <= 1) {
- printf("At least 2 NUMA nodes must be available\n");
+ ksft_print_msg("At least 2 NUMA nodes must be available\n");
return KSFT_SKIP;
}
if (ksm_write_sysfs(KSM_FP("merge_across_nodes"), merge_across_nodes))
@@ -485,7 +479,7 @@ static int check_ksm_numa_merge(int merge_type, int mapping, int prot, int timeo
numa1_map_ptr = numa_alloc_onnode(page_size, first_node);
numa2_map_ptr = numa_alloc_onnode(page_size, get_next_mem_node(first_node));
if (!numa1_map_ptr || !numa2_map_ptr) {
- perror("numa_alloc_onnode");
+ ksft_perror("numa_alloc_onnode");
return KSFT_FAIL;
}
@@ -510,13 +504,11 @@ static int check_ksm_numa_merge(int merge_type, int mapping, int prot, int timeo
numa_free(numa1_map_ptr, page_size);
numa_free(numa2_map_ptr, page_size);
- printf("OK\n");
return KSFT_PASS;
err_out:
numa_free(numa1_map_ptr, page_size);
numa_free(numa2_map_ptr, page_size);
- printf("Not OK\n");
return KSFT_FAIL;
}
@@ -529,7 +521,7 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot,
int pagemap_fd, n_normal_pages, n_huge_pages;
if (!thp_is_enabled()) {
- printf("Transparent Hugepages not available\n");
+ ksft_print_msg("Transparent Hugepages not available\n");
return KSFT_SKIP;
}
@@ -559,36 +551,35 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot,
else
n_huge_pages++;
}
- printf("Number of normal pages: %d\n", n_normal_pages);
- printf("Number of huge pages: %d\n", n_huge_pages);
+ ksft_print_msg("Number of normal pages: %d\n", n_normal_pages);
+ ksft_print_msg("Number of huge pages: %d\n", n_huge_pages);
memset(map_ptr, '*', len);
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
goto err_out;
}
if (ksm_merge_pages(merge_type, map_ptr, map_size, start_time, timeout))
goto err_out;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
goto err_out;
}
scan_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC +
(end_time.tv_nsec - start_time.tv_nsec);
- printf("Total size: %lu MiB\n", map_size / MB);
- printf("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC,
+ ksft_print_msg("Total size: %lu MiB\n", map_size / MB);
+ ksft_print_msg("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC,
scan_time_ns % NSEC_PER_SEC);
- printf("Average speed: %.3f MiB/s\n", (map_size / MB) /
+ ksft_print_msg("Average speed: %.3f MiB/s\n", (map_size / MB) /
((double)scan_time_ns / NSEC_PER_SEC));
munmap(map_ptr_orig, len + HPAGE_SIZE);
return KSFT_PASS;
err_out:
- printf("Not OK\n");
munmap(map_ptr_orig, len + HPAGE_SIZE);
return KSFT_FAIL;
}
@@ -606,30 +597,29 @@ static int ksm_merge_time(int merge_type, int mapping, int prot, int timeout, si
return KSFT_FAIL;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
goto err_out;
}
if (ksm_merge_pages(merge_type, map_ptr, map_size, start_time, timeout))
goto err_out;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
goto err_out;
}
scan_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC +
(end_time.tv_nsec - start_time.tv_nsec);
- printf("Total size: %lu MiB\n", map_size / MB);
- printf("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC,
+ ksft_print_msg("Total size: %lu MiB\n", map_size / MB);
+ ksft_print_msg("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC,
scan_time_ns % NSEC_PER_SEC);
- printf("Average speed: %.3f MiB/s\n", (map_size / MB) /
+ ksft_print_msg("Average speed: %.3f MiB/s\n", (map_size / MB) /
((double)scan_time_ns / NSEC_PER_SEC));
munmap(map_ptr, map_size);
return KSFT_PASS;
err_out:
- printf("Not OK\n");
munmap(map_ptr, map_size);
return KSFT_FAIL;
}
@@ -646,37 +636,36 @@ static int ksm_unmerge_time(int merge_type, int mapping, int prot, int timeout,
if (!map_ptr)
return KSFT_FAIL;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
goto err_out;
}
if (ksm_merge_pages(merge_type, map_ptr, map_size, start_time, timeout))
goto err_out;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
goto err_out;
}
if (ksm_unmerge_pages(map_ptr, map_size, start_time, timeout))
goto err_out;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
goto err_out;
}
scan_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC +
(end_time.tv_nsec - start_time.tv_nsec);
- printf("Total size: %lu MiB\n", map_size / MB);
- printf("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC,
+ ksft_print_msg("Total size: %lu MiB\n", map_size / MB);
+ ksft_print_msg("Total time: %ld.%09ld s\n", scan_time_ns / NSEC_PER_SEC,
scan_time_ns % NSEC_PER_SEC);
- printf("Average speed: %.3f MiB/s\n", (map_size / MB) /
+ ksft_print_msg("Average speed: %.3f MiB/s\n", (map_size / MB) /
((double)scan_time_ns / NSEC_PER_SEC));
munmap(map_ptr, map_size);
return KSFT_PASS;
err_out:
- printf("Not OK\n");
munmap(map_ptr, map_size);
return KSFT_FAIL;
}
@@ -695,24 +684,24 @@ static int ksm_cow_time(int merge_type, int mapping, int prot, int timeout, size
return KSFT_FAIL;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
return KSFT_FAIL;
}
for (size_t i = 0; i < page_count - 1; i = i + 2)
memset(map_ptr + page_size * i, '-', 1);
if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
return KSFT_FAIL;
}
cow_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC +
(end_time.tv_nsec - start_time.tv_nsec);
- printf("Total size: %lu MiB\n\n", (page_size * page_count) / MB);
- printf("Not merged pages:\n");
- printf("Total time: %ld.%09ld s\n", cow_time_ns / NSEC_PER_SEC,
+ ksft_print_msg("Total size: %lu MiB\n\n", (page_size * page_count) / MB);
+ ksft_print_msg("Not merged pages:\n");
+ ksft_print_msg("Total time: %ld.%09ld s\n", cow_time_ns / NSEC_PER_SEC,
cow_time_ns % NSEC_PER_SEC);
- printf("Average speed: %.3f MiB/s\n\n", ((page_size * (page_count / 2)) / MB) /
+ ksft_print_msg("Average speed: %.3f MiB/s\n\n", ((page_size * (page_count / 2)) / MB) /
((double)cow_time_ns / NSEC_PER_SEC));
/* Create 2000 pairs of duplicate pages */
@@ -724,30 +713,29 @@ static int ksm_cow_time(int merge_type, int mapping, int prot, int timeout, size
goto err_out;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
goto err_out;
}
for (size_t i = 0; i < page_count - 1; i = i + 2)
memset(map_ptr + page_size * i, '-', 1);
if (clock_gettime(CLOCK_MONOTONIC_RAW, &end_time)) {
- perror("clock_gettime");
+ ksft_perror("clock_gettime");
goto err_out;
}
cow_time_ns = (end_time.tv_sec - start_time.tv_sec) * NSEC_PER_SEC +
(end_time.tv_nsec - start_time.tv_nsec);
- printf("Merged pages:\n");
- printf("Total time: %ld.%09ld s\n", cow_time_ns / NSEC_PER_SEC,
+ ksft_print_msg("Merged pages:\n");
+ ksft_print_msg("Total time: %ld.%09ld s\n", cow_time_ns / NSEC_PER_SEC,
cow_time_ns % NSEC_PER_SEC);
- printf("Average speed: %.3f MiB/s\n", ((page_size * (page_count / 2)) / MB) /
+ ksft_print_msg("Average speed: %.3f MiB/s\n", ((page_size * (page_count / 2)) / MB) /
((double)cow_time_ns / NSEC_PER_SEC));
munmap(map_ptr, page_size * page_count);
return KSFT_PASS;
err_out:
- printf("Not OK\n");
munmap(map_ptr, page_size * page_count);
return KSFT_FAIL;
}
@@ -765,6 +753,10 @@ int main(int argc, char *argv[])
bool use_zero_pages = KSM_USE_ZERO_PAGES_DEFAULT;
bool merge_across_nodes = KSM_MERGE_ACROSS_NODES_DEFAULT;
long size_MB = 0;
+ const char *test_descr = "KSM merging";
+
+ ksft_print_header();
+ ksft_set_plan(1);
while ((opt = getopt(argc, argv, "dha:p:l:z:m:s:t:MUZNPCHD")) != -1) {
switch (opt) {
@@ -773,17 +765,13 @@ int main(int argc, char *argv[])
break;
case 'p':
page_count = atol(optarg);
- if (page_count <= 0) {
- printf("The number of pages must be greater than 0\n");
- return KSFT_FAIL;
- }
+ if (page_count <= 0)
+ ksft_exit_fail_msg("The number of pages must be greater than 0\n");
break;
case 'l':
ksm_scan_limit_sec = atoi(optarg);
- if (ksm_scan_limit_sec <= 0) {
- printf("Timeout value must be greater than 0\n");
- return KSFT_FAIL;
- }
+ if (ksm_scan_limit_sec <= 0)
+ ksft_exit_fail_msg("Timeout value must be greater than 0\n");
break;
case 'h':
print_help();
@@ -805,19 +793,15 @@ int main(int argc, char *argv[])
break;
case 's':
size_MB = atoi(optarg);
- if (size_MB <= 0) {
- printf("Size must be greater than 0\n");
- return KSFT_FAIL;
- }
+ if (size_MB <= 0)
+ ksft_exit_fail_msg("Size must be greater than 0\n");
break;
case 't':
{
int tmp = atoi(optarg);
- if (tmp < 0 || tmp > KSM_MERGE_LAST) {
- printf("Invalid merge type\n");
- return KSFT_FAIL;
- }
+ if (tmp < 0 || tmp > KSM_MERGE_LAST)
+ ksft_exit_fail_msg("Invalid merge type\n");
merge_type = tmp;
}
break;
@@ -845,82 +829,80 @@ int main(int argc, char *argv[])
test_name = KSM_COW_TIME;
break;
default:
- return KSFT_FAIL;
+ ksft_exit_fail_msg("Unknown option\n");
}
}
if (prot == 0)
prot = str_to_prot(KSM_PROT_STR_DEFAULT);
- if (access(KSM_SYSFS_PATH, F_OK)) {
- printf("Config KSM not enabled\n");
- return KSFT_SKIP;
- }
+ if (access(KSM_SYSFS_PATH, F_OK))
+ ksft_exit_skip("Config KSM not enabled\n");
- if (ksm_save_def(&ksm_sysfs_old)) {
- printf("Cannot save default tunables\n");
- return KSFT_FAIL;
- }
+ if (ksm_save_def(&ksm_sysfs_old))
+ ksft_exit_fail_msg("Cannot save default tunables\n");
if (ksm_write_sysfs(KSM_FP("run"), 2) ||
ksm_write_sysfs(KSM_FP("sleep_millisecs"), 0) ||
numa_available() ? 0 :
ksm_write_sysfs(KSM_FP("merge_across_nodes"), 1) ||
ksm_write_sysfs(KSM_FP("pages_to_scan"), page_count))
- return KSFT_FAIL;
+ ksft_exit_fail_msg("Cannot set up KSM tunables\n");
switch (test_name) {
case CHECK_KSM_MERGE:
+ test_descr = "KSM merging";
ret = check_ksm_merge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot, page_count,
ksm_scan_limit_sec, page_size);
break;
case CHECK_KSM_UNMERGE:
+ test_descr = "KSM unmerging";
ret = check_ksm_unmerge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot,
ksm_scan_limit_sec, page_size);
break;
case CHECK_KSM_ZERO_PAGE_MERGE:
+ test_descr = "KSM zero page merging";
ret = check_ksm_zero_page_merge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot,
page_count, ksm_scan_limit_sec, use_zero_pages,
page_size);
break;
case CHECK_KSM_NUMA_MERGE:
+ test_descr = "KSM NUMA merging";
ret = check_ksm_numa_merge(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot,
ksm_scan_limit_sec, merge_across_nodes, page_size);
break;
case KSM_MERGE_TIME:
- if (size_MB == 0) {
- printf("Option '-s' is required.\n");
- return KSFT_FAIL;
- }
+ if (size_MB == 0)
+ ksft_exit_fail_msg("Option '-s' is required\n");
+ test_descr = "KSM merge time";
ret = ksm_merge_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot,
ksm_scan_limit_sec, size_MB);
break;
case KSM_MERGE_TIME_HUGE_PAGES:
- if (size_MB == 0) {
- printf("Option '-s' is required.\n");
- return KSFT_FAIL;
- }
+ if (size_MB == 0)
+ ksft_exit_fail_msg("Option '-s' is required\n");
+ test_descr = "KSM merge time with huge pages";
ret = ksm_merge_hugepages_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot,
ksm_scan_limit_sec, size_MB);
break;
case KSM_UNMERGE_TIME:
- if (size_MB == 0) {
- printf("Option '-s' is required.\n");
- return KSFT_FAIL;
- }
+ if (size_MB == 0)
+ ksft_exit_fail_msg("Option '-s' is required\n");
+ test_descr = "KSM unmerge time";
ret = ksm_unmerge_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot,
ksm_scan_limit_sec, size_MB);
break;
case KSM_COW_TIME:
+ test_descr = "KSM COW time";
ret = ksm_cow_time(merge_type, MAP_PRIVATE | MAP_ANONYMOUS, prot,
ksm_scan_limit_sec, page_size);
break;
}
- if (ksm_restore(&ksm_sysfs_old)) {
- printf("Cannot restore default tunables\n");
- return KSFT_FAIL;
- }
+ if (ksm_restore(&ksm_sysfs_old))
+ ksft_print_msg("Cannot restore default tunables\n");
+
+ ksft_test_result_report(ret, "%s\n", test_descr);
- return ret;
+ ksft_finished();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 15/53] selftests/mm: protection_keys: use descriptive test names in TAP output
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (13 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 14/53] selftests/mm: ksm_tests: use kselftest framework Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 16:51 ` Mark Brown
2026-04-06 14:16 ` [PATCH 16/53] selftests/mm: protection_keys: use kselftest framework Mike Rapoport
` (37 subsequent siblings)
52 siblings, 1 reply; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Replace the numeric test index in TAP output with the actual test
function name.
Use a structure containing function pointer and its name rather than
only the function pointer in the pkey_tests array.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/protection_keys.c | 55 +++++++++++---------
1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index 2085982dba69..80c6124e8378 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -1692,29 +1692,36 @@ static void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey)
pkey_assert(sret < 0);
}
-static void (*pkey_tests[])(int *ptr, u16 pkey) = {
- test_read_of_write_disabled_region,
- test_read_of_access_disabled_region,
- test_read_of_access_disabled_region_with_page_already_mapped,
- test_write_of_write_disabled_region,
- test_write_of_write_disabled_region_with_page_already_mapped,
- test_write_of_access_disabled_region,
- test_write_of_access_disabled_region_with_page_already_mapped,
- test_kernel_write_of_access_disabled_region,
- test_kernel_write_of_write_disabled_region,
- test_kernel_gup_of_access_disabled_region,
- test_kernel_gup_write_to_write_disabled_region,
- test_executing_on_unreadable_memory,
- test_implicit_mprotect_exec_only_memory,
- test_mprotect_with_pkey_0,
- test_ptrace_of_child,
- test_pkey_init_state,
- test_pkey_syscalls_on_non_allocated_pkey,
- test_pkey_syscalls_bad_args,
- test_pkey_alloc_exhaust,
- test_pkey_alloc_free_attach_pkey0,
+struct pkey_test {
+ void (*func)(int *ptr, u16 pkey);
+ const char *name;
+};
+
+#define PKEY_TEST(fn) { fn, #fn }
+
+static struct pkey_test pkey_tests[] = {
+ PKEY_TEST(test_read_of_write_disabled_region),
+ PKEY_TEST(test_read_of_access_disabled_region),
+ PKEY_TEST(test_read_of_access_disabled_region_with_page_already_mapped),
+ PKEY_TEST(test_write_of_write_disabled_region),
+ PKEY_TEST(test_write_of_write_disabled_region_with_page_already_mapped),
+ PKEY_TEST(test_write_of_access_disabled_region),
+ PKEY_TEST(test_write_of_access_disabled_region_with_page_already_mapped),
+ PKEY_TEST(test_kernel_write_of_access_disabled_region),
+ PKEY_TEST(test_kernel_write_of_write_disabled_region),
+ PKEY_TEST(test_kernel_gup_of_access_disabled_region),
+ PKEY_TEST(test_kernel_gup_write_to_write_disabled_region),
+ PKEY_TEST(test_executing_on_unreadable_memory),
+ PKEY_TEST(test_implicit_mprotect_exec_only_memory),
+ PKEY_TEST(test_mprotect_with_pkey_0),
+ PKEY_TEST(test_ptrace_of_child),
+ PKEY_TEST(test_pkey_init_state),
+ PKEY_TEST(test_pkey_syscalls_on_non_allocated_pkey),
+ PKEY_TEST(test_pkey_syscalls_bad_args),
+ PKEY_TEST(test_pkey_alloc_exhaust),
+ PKEY_TEST(test_pkey_alloc_free_attach_pkey0),
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
- test_ptrace_modifies_pkru,
+ PKEY_TEST(test_ptrace_modifies_pkru),
#endif
};
@@ -1735,7 +1742,7 @@ static void run_tests_once(void)
dprintf1("test %d starting with pkey: %d\n", test_nr, pkey);
ptr = malloc_pkey(PAGE_SIZE, prot, pkey);
dprintf1("test %d starting...\n", test_nr);
- pkey_tests[test_nr](ptr, pkey);
+ pkey_tests[test_nr].func(ptr, pkey);
dprintf1("freeing test memory: %p\n", ptr);
free_pkey_malloc(ptr);
sys_pkey_free(pkey);
@@ -1746,7 +1753,7 @@ static void run_tests_once(void)
tracing_off();
close_test_fds();
- printf("test %2d PASSED (iteration %d)\n", test_nr, iteration_nr);
+ printf("test %s PASSED (iteration %d)\n", pkey_tests[test_nr].name, iteration_nr);
dprintf1("======================\n\n");
}
iteration_nr++;
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 16/53] selftests/mm: protection_keys: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (14 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 15/53] selftests/mm: protection_keys: use descriptive test names in TAP output Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 17:02 ` Mark Brown
2026-04-06 14:16 ` [PATCH 17/53] selftests/mm: uffd-stress: " Mike Rapoport
` (36 subsequent siblings)
52 siblings, 1 reply; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert protection_keys test to use kselftest framework for reporting
and tracking successful and failing runs.
Adjust dprintf0() printouts to use "#" in the beginning of the line for
TAP compatibility and add fflush(stdout) in the end of the test to
ensure all the ksft_print_*() messages are really output.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/pkey-helpers.h | 6 +++--
tools/testing/selftests/mm/protection_keys.c | 27 ++++++++++++--------
2 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/mm/pkey-helpers.h b/tools/testing/selftests/mm/pkey-helpers.h
index 7c29f075e40b..ae010b075417 100644
--- a/tools/testing/selftests/mm/pkey-helpers.h
+++ b/tools/testing/selftests/mm/pkey-helpers.h
@@ -71,10 +71,12 @@ static inline void sigsafe_printf(const char *format, ...)
extern void abort_hooks(void);
#define pkey_assert(condition) do { \
if (!(condition)) { \
- dprintf0("assert() at %s::%d test_nr: %d iteration: %d\n", \
+ dprintf0("# assert() at %s::%d test_nr: %d iteration: %d\n", \
__FILE__, __LINE__, \
test_nr, iteration_nr); \
- dprintf0("errno at assert: %d", errno); \
+ dprintf0("# errno at assert: %d\n", errno); \
+ ksft_test_result_fail("test %d (iteration %d)\n", \
+ test_nr, iteration_nr); \
abort_hooks(); \
exit(__LINE__); \
} \
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index 80c6124e8378..c069250969f5 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -136,6 +136,7 @@ static void tracing_off(void)
void abort_hooks(void)
{
+ fflush(stdout);
fprintf(stderr, "running %s()...\n", __func__);
tracing_off();
#ifdef SLEEP_ON_ABORT
@@ -370,8 +371,8 @@ static void signal_handler(int signum, siginfo_t *si, void *vucontext)
if ((si->si_code == SEGV_MAPERR) ||
(si->si_code == SEGV_ACCERR) ||
(si->si_code == SEGV_BNDERR)) {
- printf("non-PK si_code, exiting...\n");
- exit(4);
+ dprintf0("# non-PK si_code: %d, exiting...\n", si->si_code);
+ exit(1);
}
si_pkey_ptr = siginfo_get_pkey_ptr(si);
@@ -719,7 +720,7 @@ static void setup_hugetlbfs(void)
long hpagesz_mb;
if (geteuid() != 0) {
- fprintf(stderr, "WARNING: not run as root, can not do hugetlb test\n");
+ ksft_print_msg("WARNING: not run as root, can not do hugetlb test\n");
return;
}
@@ -855,7 +856,7 @@ void expected_pkey_fault(int pkey)
#define do_not_expect_pkey_fault(msg) do { \
if (last_pkey_faults != pkey_faults) \
- dprintf0("unexpected PKey fault: %s\n", msg); \
+ dprintf0("# unexpected PKey fault: %s\n", msg); \
pkey_assert(last_pkey_faults == pkey_faults); \
} while (0)
@@ -1753,7 +1754,7 @@ static void run_tests_once(void)
tracing_off();
close_test_fds();
- printf("test %s PASSED (iteration %d)\n", pkey_tests[test_nr].name, iteration_nr);
+ ksft_test_result_pass("test %s (iteration %d)\n", pkey_tests[test_nr].name, iteration_nr);
dprintf1("======================\n\n");
}
iteration_nr++;
@@ -1773,27 +1774,31 @@ int main(void)
setup_handlers();
- printf("has pkeys: %d\n", pkeys_supported);
+ ksft_print_header();
if (!pkeys_supported) {
int size = PAGE_SIZE;
int *ptr;
- printf("running PKEY tests for unsupported CPU/OS\n");
+ ksft_set_plan(1);
+ ksft_print_msg("running PKEY tests for unsupported CPU/OS\n");
ptr = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
assert(ptr != (void *)-1);
test_mprotect_pkey_on_unsupported_cpu(ptr, 1);
- exit(0);
+ ksft_test_result_pass("pkey on unsupported CPU/OS\n");
+ ksft_finished();
}
+ ksft_set_plan(ARRAY_SIZE(pkey_tests) * nr_iterations);
+
pkey_setup_shadow();
- printf("startup pkey_reg: %016llx\n", read_pkey_reg());
+ ksft_print_msg("startup pkey_reg: %016llx\n", read_pkey_reg());
setup_hugetlbfs();
while (nr_iterations-- > 0)
run_tests_once();
- printf("done (all tests OK)\n");
- return 0;
+ ksft_finished();
+ fflush(stdout);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 17/53] selftests/mm: uffd-stress: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (15 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 16/53] selftests/mm: protection_keys: use kselftest framework Mike Rapoport
@ 2026-04-06 14:16 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 18/53] selftests/mm: uffd-unit-tests: " Mike Rapoport
` (35 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:16 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert uffd-stress test to use kselftest framework for reporting and
tracking successful and failing runs.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/uffd-stress.c | 41 +++++++++++-------------
1 file changed, 19 insertions(+), 22 deletions(-)
diff --git a/tools/testing/selftests/mm/uffd-stress.c b/tools/testing/selftests/mm/uffd-stress.c
index 700fbaa18d44..e92a85463eb1 100644
--- a/tools/testing/selftests/mm/uffd-stress.c
+++ b/tools/testing/selftests/mm/uffd-stress.c
@@ -286,19 +286,12 @@ static int userfaultfd_stress(uffd_global_test_opts_t *gopts)
pthread_attr_setstacksize(&attr, 16*1024*1024);
while (bounces--) {
- printf("bounces: %d, mode:", bounces);
- if (bounces & BOUNCE_RANDOM)
- printf(" rnd");
- if (bounces & BOUNCE_RACINGFAULTS)
- printf(" racing");
- if (bounces & BOUNCE_VERIFY)
- printf(" ver");
- if (bounces & BOUNCE_POLL)
- printf(" poll");
- else
- printf(" read");
- printf(", ");
- fflush(stdout);
+ ksft_print_msg("bounces: %d, mode:%s%s%s%s, ",
+ bounces,
+ bounces & BOUNCE_RANDOM ? " rnd" : "",
+ bounces & BOUNCE_RACINGFAULTS ? " racing" : "",
+ bounces & BOUNCE_VERIFY ? " ver" : "",
+ bounces & BOUNCE_POLL ? " poll" : " read");
if (bounces & BOUNCE_POLL)
fcntl(gopts->uffd, F_SETFL, gopts->uffd_flags | O_NONBLOCK);
@@ -456,6 +449,9 @@ int main(int argc, char **argv)
unsigned long nr_cpus;
size_t bytes;
+ ksft_print_header();
+ ksft_set_plan(1);
+
gopts = (uffd_global_test_opts_t *) malloc(sizeof(uffd_global_test_opts_t));
if (argc < 4)
@@ -484,10 +480,8 @@ int main(int argc, char **argv)
* for racy extra reservation of hugepages.
*/
if (gopts->test_type == TEST_HUGETLB &&
- get_free_hugepages() < 2 * (bytes / gopts->page_size) + gopts->nr_parallel - 1) {
- printf("skip: Skipping userfaultfd... not enough hugepages\n");
- return KSFT_SKIP;
- }
+ get_free_hugepages() < 2 * (bytes / gopts->page_size) + gopts->nr_parallel - 1)
+ ksft_exit_skip("Skipping userfaultfd... not enough hugepages\n");
gopts->nr_pages_per_cpu = bytes / gopts->page_size / gopts->nr_parallel;
if (!gopts->nr_pages_per_cpu) {
@@ -503,9 +497,12 @@ int main(int argc, char **argv)
}
gopts->nr_pages = gopts->nr_pages_per_cpu * gopts->nr_parallel;
- printf("nr_pages: %lu, nr_pages_per_cpu: %lu\n",
- gopts->nr_pages, gopts->nr_pages_per_cpu);
- return userfaultfd_stress(gopts);
+ ksft_print_msg("nr_pages: %lu, nr_pages_per_cpu: %lu\n",
+ gopts->nr_pages, gopts->nr_pages_per_cpu);
+
+ ksft_test_result(!userfaultfd_stress(gopts),
+ "uffd-stress %s\n", argv[1]);
+ ksft_finished();
}
#else /* __NR_userfaultfd */
@@ -514,8 +511,8 @@ int main(int argc, char **argv)
int main(void)
{
- printf("skip: Skipping userfaultfd test (missing __NR_userfaultfd)\n");
- return KSFT_SKIP;
+ ksft_print_header();
+ ksft_exit_skip("missing __NR_userfaultfd definition\n");
}
#endif /* __NR_userfaultfd */
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 18/53] selftests/mm: uffd-unit-tests: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (16 preceding siblings ...)
2026-04-06 14:16 ` [PATCH 17/53] selftests/mm: uffd-stress: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 19/53] selftests/mm: va_high_addr_switch: " Mike Rapoport
` (34 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert uffd-unit-tests to use kselftest framework for reporting and
tracking successful and failing runs.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/uffd-unit-tests.c | 79 +++++++++++---------
1 file changed, 44 insertions(+), 35 deletions(-)
diff --git a/tools/testing/selftests/mm/uffd-unit-tests.c b/tools/testing/selftests/mm/uffd-unit-tests.c
index 6f5e404a446c..1a33db281f8a 100644
--- a/tools/testing/selftests/mm/uffd-unit-tests.c
+++ b/tools/testing/selftests/mm/uffd-unit-tests.c
@@ -86,39 +86,24 @@ typedef struct {
uffd_test_case_ops_t *test_case_ops;
} uffd_test_case_t;
-static void uffd_test_report(void)
-{
- printf("Userfaults unit tests: pass=%u, skip=%u, fail=%u (total=%u)\n",
- ksft_get_pass_cnt(),
- ksft_get_xskip_cnt(),
- ksft_get_fail_cnt(),
- ksft_test_num());
-}
+static char current_test[256];
static void uffd_test_pass(void)
{
- printf("done\n");
- ksft_inc_pass_cnt();
+ ksft_test_result_pass("%s\n", current_test);
}
#define uffd_test_start(...) do { \
- printf("Testing "); \
- printf(__VA_ARGS__); \
- printf("... "); \
- fflush(stdout); \
+ snprintf(current_test, sizeof(current_test), __VA_ARGS__); \
} while (0)
#define uffd_test_fail(...) do { \
- printf("failed [reason: "); \
- printf(__VA_ARGS__); \
- printf("]\n"); \
- ksft_inc_fail_cnt(); \
+ ksft_test_result_fail("%s\n", current_test); \
} while (0)
static void uffd_test_skip(const char *message)
{
- printf("skipped [reason: %s]\n", message);
- ksft_inc_xskip_cnt();
+ ksft_test_result_skip("%s (%s)\n", current_test, message);
}
/*
@@ -1701,6 +1686,26 @@ static void usage(const char *prog)
exit(KSFT_FAIL);
}
+static int uffd_count_tests(int n_tests, int n_mems, const char *test_filter)
+{
+ uffd_test_case_t *test;
+ int i, j, count = 0;
+
+ if (!test_filter)
+ count += 2; /* test_uffd_api(false) + test_uffd_api(true) */
+
+ for (i = 0; i < n_tests; i++) {
+ test = &uffd_tests[i];
+ if (test_filter && !strstr(test->name, test_filter))
+ continue;
+ for (j = 0; j < n_mems; j++)
+ if (test->mem_targets & mem_types[j].mem_flag)
+ count++;
+ }
+
+ return count;
+}
+
int main(int argc, char *argv[])
{
int n_tests = sizeof(uffd_tests) / sizeof(uffd_test_case_t);
@@ -1730,24 +1735,31 @@ int main(int argc, char *argv[])
}
}
- if (!test_filter && !list_only) {
+ if (list_only) {
+ for (i = 0; i < n_tests; i++) {
+ test = &uffd_tests[i];
+ if (test_filter && !strstr(test->name, test_filter))
+ continue;
+ printf("%s\n", test->name);
+ }
+ return KSFT_PASS;
+ }
+
+ ksft_print_header();
+ ksft_set_plan(uffd_count_tests(n_tests, n_mems, test_filter));
+
+ if (!test_filter) {
has_uffd = test_uffd_api(false);
has_uffd |= test_uffd_api(true);
- if (!has_uffd) {
- printf("Userfaultfd not supported or unprivileged, skip all tests\n");
- exit(KSFT_SKIP);
- }
+ if (!has_uffd)
+ ksft_exit_skip("Userfaultfd not supported or unprivileged\n");
}
for (i = 0; i < n_tests; i++) {
test = &uffd_tests[i];
if (test_filter && !strstr(test->name, test_filter))
continue;
- if (list_only) {
- printf("%s\n", test->name);
- continue;
- }
for (j = 0; j < n_mems; j++) {
mem_type = &mem_types[j];
@@ -1794,10 +1806,7 @@ int main(int argc, char *argv[])
}
}
- if (!list_only)
- uffd_test_report();
-
- return ksft_get_fail_cnt() ? KSFT_FAIL : KSFT_PASS;
+ ksft_finished();
}
#else /* __NR_userfaultfd */
@@ -1806,8 +1815,8 @@ int main(int argc, char *argv[])
int main(void)
{
- printf("Skipping %s (missing __NR_userfaultfd)\n", __file__);
- return KSFT_SKIP;
+ ksft_print_header();
+ ksft_exit_skip("missing __NR_userfaultfd definition\n");
}
#endif /* __NR_userfaultfd */
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 19/53] selftests/mm: va_high_addr_switch: use kselftest framework
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (17 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 18/53] selftests/mm: uffd-unit-tests: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 20/53] selftests/mm: add atexit() and signal handlers to thp_settings Mike Rapoport
` (33 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Convert va_high_addr_switch test to use kselftest framework for
reporting and tracking successful and failing runs.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
.../selftests/mm/va_high_addr_switch.c | 39 +++++++++----------
1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/tools/testing/selftests/mm/va_high_addr_switch.c b/tools/testing/selftests/mm/va_high_addr_switch.c
index 51401e081b20..5741fd057640 100644
--- a/tools/testing/selftests/mm/va_high_addr_switch.c
+++ b/tools/testing/selftests/mm/va_high_addr_switch.c
@@ -257,40 +257,33 @@ void testcases_init(void)
switch_hint = addr_switch_hint;
}
-static int run_test(struct testcase *test, int count)
+static void run_test(struct testcase *test, int count)
{
void *p;
- int i, ret = KSFT_PASS;
+ int i;
for (i = 0; i < count; i++) {
struct testcase *t = test + i;
p = mmap(t->addr, t->size, PROT_READ | PROT_WRITE, t->flags, -1, 0);
-
- printf("%s: %p - ", t->msg, p);
-
if (p == MAP_FAILED) {
- printf("FAILED\n");
- ret = KSFT_FAIL;
+ ksft_test_result_fail("%s: MAP_FAILED\n", t->msg);
continue;
}
if (t->low_addr_required && p >= (void *)(switch_hint)) {
- printf("FAILED\n");
- ret = KSFT_FAIL;
+ ksft_test_result_fail("%s: %p not below switch hint\n", t->msg, p);
} else {
/*
* Do a dereference of the address returned so that we catch
* bugs in page fault handling
*/
memset(p, 0, t->size);
- printf("OK\n");
+ ksft_test_result_pass("%s: %p\n", t->msg, p);
}
if (!t->keep_mapped)
munmap(p, t->size);
}
-
- return ret;
}
#ifdef __aarch64__
@@ -322,19 +315,23 @@ static int supported_arch(void)
int main(int argc, char **argv)
{
- int ret, hugetlb_ret = KSFT_PASS;
+ bool run_hugetlb = false;
+
+ ksft_print_header();
if (!supported_arch())
- return KSFT_SKIP;
+ ksft_exit_skip("Architecture not supported\n");
+
+ if (argc == 2 && !strcmp(argv[1], "--run-hugetlb"))
+ run_hugetlb = true;
testcases_init();
- ret = run_test(testcases, sz_testcases);
- if (argc == 2 && !strcmp(argv[1], "--run-hugetlb"))
- hugetlb_ret = run_test(hugetlb_testcases, sz_hugetlb_testcases);
+ ksft_set_plan(sz_testcases + (run_hugetlb ? sz_hugetlb_testcases : 0));
+
+ run_test(testcases, sz_testcases);
+ if (run_hugetlb)
+ run_test(hugetlb_testcases, sz_hugetlb_testcases);
- if (ret == KSFT_PASS && hugetlb_ret == KSFT_PASS)
- return KSFT_PASS;
- else
- return KSFT_FAIL;
+ ksft_finished();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 20/53] selftests/mm: add atexit() and signal handlers to thp_settings
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (18 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 19/53] selftests/mm: va_high_addr_switch: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 21/53] selftests/mm: rename thp_settings.[ch] to hugepage_settings.[ch] Mike Rapoport
` (32 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
khugepaged registers atexit() and signal handlers that ensure that THP
settings are restored regardless of how the test exited.
Make these handlers available for all users of thp_settings.
The call to thp_save_settings() installs thp_restore_settings as the
atexit() callback and makes sure that signals that kill a process would
still call exit() and atexit() callback.
Update child process in tests using thp_settings to use _exit() instead
of exit() to avoid altering THP settings in the middle of a test.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/cow.c | 21 +++++------
tools/testing/selftests/mm/khugepaged.c | 40 +++------------------
tools/testing/selftests/mm/thp_settings.c | 28 ++++++++++++++-
tools/testing/selftests/mm/uffd-wp-mremap.c | 4 ---
4 files changed, 39 insertions(+), 54 deletions(-)
diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
index d9c69c04b67d..6abdcb30aba8 100644
--- a/tools/testing/selftests/mm/cow.c
+++ b/tools/testing/selftests/mm/cow.c
@@ -202,7 +202,7 @@ static void do_test_cow_in_parent(char *mem, size_t size, bool do_mprotect,
log_test_result(KSFT_FAIL);
goto close_comm_pipes;
} else if (!ret) {
- exit(fn(mem, size, &comm_pipes));
+ _exit(fn(mem, size, &comm_pipes));
}
while (read(comm_pipes.child_ready[0], &buf, 1) != 1)
@@ -333,7 +333,7 @@ static void do_test_vmsplice_in_parent(char *mem, size_t size,
;
/* Modify page content in the child. */
memset(mem, 0xff, size);
- exit(0);
+ _exit(0);
}
if (!before_fork) {
@@ -480,7 +480,7 @@ static void do_test_iouring(char *mem, size_t size, bool use_fork)
write(comm_pipes.child_ready[1], "0", 1);
while (read(comm_pipes.parent_ready[0], &buf, 1) != 1)
;
- exit(0);
+ _exit(0);
}
while (read(comm_pipes.child_ready[0], &buf, 1) != 1)
@@ -645,7 +645,7 @@ static void do_test_ro_pin(char *mem, size_t size, enum ro_pin_test test,
write(comm_pipes.child_ready[1], "0", 1);
while (read(comm_pipes.parent_ready[0], &buf, 1) != 1)
;
- exit(0);
+ _exit(0);
}
/* Wait until our child is ready. */
@@ -956,7 +956,7 @@ static void do_run_with_thp(test_fn fn, enum thp_run thp_run, size_t thpsize)
log_test_result(KSFT_FAIL);
goto munmap;
} else if (!ret) {
- exit(0);
+ _exit(0);
}
wait(&ret);
/* Allow for sharing all pages again. */
@@ -1347,13 +1347,13 @@ static void do_test_anon_thp_collapse(char *mem, size_t size,
switch (test) {
case ANON_THP_COLLAPSE_UNSHARED:
case ANON_THP_COLLAPSE_FULLY_SHARED:
- exit(child_memcmp_fn(mem, size, &comm_pipes));
+ _exit(child_memcmp_fn(mem, size, &comm_pipes));
break;
case ANON_THP_COLLAPSE_LOWER_SHARED:
- exit(child_memcmp_fn(mem, size / 2, &comm_pipes));
+ _exit(child_memcmp_fn(mem, size / 2, &comm_pipes));
break;
case ANON_THP_COLLAPSE_UPPER_SHARED:
- exit(child_memcmp_fn(mem + size / 2, size / 2,
+ _exit(child_memcmp_fn(mem + size / 2, size / 2,
&comm_pipes));
break;
default:
@@ -1911,10 +1911,5 @@ int main(int argc, char **argv)
run_anon_thp_test_cases();
run_non_anon_test_cases();
- if (pmdsize) {
- /* Only if THP is supported. */
- thp_restore_settings();
- }
-
ksft_finished();
}
diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c
index ba0a9e14e600..fac11b7e7443 100644
--- a/tools/testing/selftests/mm/khugepaged.c
+++ b/tools/testing/selftests/mm/khugepaged.c
@@ -72,7 +72,6 @@ struct file_info {
};
static struct file_info finfo;
-static bool skip_settings_restore;
static int exit_status;
static void success(const char *msg)
@@ -92,25 +91,6 @@ static void skip(const char *msg)
exit_status = KSFT_SKIP;
}
-static void restore_settings_atexit(void)
-{
- if (skip_settings_restore)
- return;
-
- ksft_print_msg("Restore THP and khugepaged settings...");
- thp_restore_settings();
- success("OK");
-
- skip_settings_restore = true;
- ksft_finished();
-}
-
-static void restore_settings(int sig)
-{
- /* exit() will invoke the restore_settings_atexit handler. */
- exit(sig ? KSFT_FAIL : exit_status);
-}
-
static void save_settings(void)
{
ksft_print_msg("Save THP and khugepaged settings...");
@@ -119,12 +99,6 @@ static void save_settings(void)
thp_save_settings();
success("OK");
-
- atexit(restore_settings_atexit);
- signal(SIGTERM, restore_settings);
- signal(SIGINT, restore_settings);
- signal(SIGHUP, restore_settings);
- signal(SIGQUIT, restore_settings);
}
static void get_finfo(const char *dir)
@@ -840,8 +814,6 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops)
ksft_print_msg("Share small page over fork()...");
if (!fork()) {
/* Do not touch settings on child exit */
- skip_settings_restore = true;
-
if (ops->check_huge(p, 0))
success("OK");
else
@@ -853,7 +825,7 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops)
validate_memory(p, 0, page_size);
ops->cleanup_area(p, hpage_pmd_size);
- exit(exit_status);
+ _exit(exit_status);
}
wait(&wstatus);
@@ -878,8 +850,6 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o
ksft_print_msg("Share huge page over fork()...");
if (!fork()) {
/* Do not touch settings on child exit */
- skip_settings_restore = true;
-
if (ops->check_huge(p, 1))
success("OK");
else
@@ -902,7 +872,7 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o
validate_memory(p, 0, hpage_pmd_size);
ops->cleanup_area(p, hpage_pmd_size);
- exit(exit_status);
+ _exit(exit_status);
}
wait(&wstatus);
@@ -928,8 +898,6 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops
ksft_print_msg("Share huge page over fork()...");
if (!fork()) {
/* Do not touch settings on child exit */
- skip_settings_restore = true;
-
if (ops->check_huge(p, 1))
success("OK");
else
@@ -962,7 +930,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops
validate_memory(p, 0, hpage_pmd_size);
ops->cleanup_area(p, hpage_pmd_size);
- exit(exit_status);
+ _exit(exit_status);
}
wait(&wstatus);
@@ -1258,5 +1226,5 @@ int main(int argc, char **argv)
t->fn(t->ctx, t->ops);
}
- restore_settings(0);
+ ksft_finished();
}
diff --git a/tools/testing/selftests/mm/thp_settings.c b/tools/testing/selftests/mm/thp_settings.c
index e748ebfb3d4e..f38ba8a27b30 100644
--- a/tools/testing/selftests/mm/thp_settings.c
+++ b/tools/testing/selftests/mm/thp_settings.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <fcntl.h>
#include <limits.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -15,6 +16,7 @@ static struct thp_settings settings_stack[MAX_SETTINGS_DEPTH];
static int settings_index;
static struct thp_settings saved_settings;
static char dev_queue_read_ahead_path[PATH_MAX];
+static bool thp_settings_saved;
static const char * const thp_enabled_strings[] = {
"never",
@@ -298,12 +300,36 @@ void thp_pop_settings(void)
void thp_restore_settings(void)
{
- thp_write_settings(&saved_settings);
+ if (thp_settings_saved)
+ thp_write_settings(&saved_settings);
+}
+
+static void thp_restore_settings_atexit(void)
+{
+ thp_restore_settings();
+}
+
+static void thp_restore_settings_sighandler(int sig)
+{
+ /* exit() will invoke the thp_restore_settings_atexit handler. */
+ exit(KSFT_FAIL);
}
void thp_save_settings(void)
{
thp_read_settings(&saved_settings);
+
+ /*
+ * setup exit hooks to make sure THP settings are restored on graceful
+ * and error exits and signals
+ */
+ atexit(thp_restore_settings_atexit);
+ signal(SIGTERM, thp_restore_settings_sighandler);
+ signal(SIGINT, thp_restore_settings_sighandler);
+ signal(SIGHUP, thp_restore_settings_sighandler);
+ signal(SIGQUIT, thp_restore_settings_sighandler);
+
+ thp_settings_saved = true;
}
void thp_set_read_ahead_path(char *path)
diff --git a/tools/testing/selftests/mm/uffd-wp-mremap.c b/tools/testing/selftests/mm/uffd-wp-mremap.c
index 17186d4a4147..516c35d236e1 100644
--- a/tools/testing/selftests/mm/uffd-wp-mremap.c
+++ b/tools/testing/selftests/mm/uffd-wp-mremap.c
@@ -368,10 +368,6 @@ int main(int argc, char **argv)
tc->swapout, tc->hugetlb);
}
- /* If THP is supported, restore original THP settings. */
- if (nr_thpsizes)
- thp_restore_settings();
-
i = ksft_get_fail_cnt();
if (i)
ksft_exit_fail_msg("%d out of %d tests failed\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 21/53] selftests/mm: rename thp_settings.[ch] to hugepage_settings.[ch]
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (19 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 20/53] selftests/mm: add atexit() and signal handlers to thp_settings Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 22/53] selftests/mm: move HugeTLB helpers to hugepage_settings Mike Rapoport
` (31 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
... for upcoming addition of HugeTLB helpers.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/Makefile | 4 ++--
tools/testing/selftests/mm/cow.c | 2 +-
tools/testing/selftests/mm/folio_split_race_test.c | 2 +-
tools/testing/selftests/mm/guard-regions.c | 2 +-
.../selftests/mm/{thp_settings.c => hugepage_settings.c} | 2 +-
.../selftests/mm/{thp_settings.h => hugepage_settings.h} | 0
tools/testing/selftests/mm/khugepaged.c | 2 +-
tools/testing/selftests/mm/ksm_tests.c | 2 +-
tools/testing/selftests/mm/migration.c | 2 +-
tools/testing/selftests/mm/prctl_thp_disable.c | 2 +-
tools/testing/selftests/mm/soft-dirty.c | 2 +-
tools/testing/selftests/mm/split_huge_page_test.c | 2 +-
tools/testing/selftests/mm/transhuge-stress.c | 2 +-
tools/testing/selftests/mm/uffd-wp-mremap.c | 2 +-
14 files changed, 14 insertions(+), 14 deletions(-)
rename tools/testing/selftests/mm/{thp_settings.c => hugepage_settings.c} (99%)
rename tools/testing/selftests/mm/{thp_settings.h => hugepage_settings.h} (100%)
diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index a6955660a806..a1d103b38485 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -186,8 +186,8 @@ TEST_FILES += write_hugetlb_memory.sh
include ../lib.mk
-$(TEST_GEN_PROGS): vm_util.c thp_settings.c
-$(TEST_GEN_FILES): vm_util.c thp_settings.c
+$(TEST_GEN_PROGS): vm_util.c hugepage_settings.c
+$(TEST_GEN_FILES): vm_util.c hugepage_settings.c
$(OUTPUT)/uffd-stress: uffd-common.c
$(OUTPUT)/uffd-unit-tests: uffd-common.c
diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
index 6abdcb30aba8..4321f4208fe3 100644
--- a/tools/testing/selftests/mm/cow.c
+++ b/tools/testing/selftests/mm/cow.c
@@ -29,7 +29,7 @@
#include "../../../../mm/gup_test.h"
#include "kselftest.h"
#include "vm_util.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
static size_t pagesize;
static int pagemap_fd;
diff --git a/tools/testing/selftests/mm/folio_split_race_test.c b/tools/testing/selftests/mm/folio_split_race_test.c
index ff026f183ac7..7ede4793c778 100644
--- a/tools/testing/selftests/mm/folio_split_race_test.c
+++ b/tools/testing/selftests/mm/folio_split_race_test.c
@@ -25,7 +25,7 @@
#include <unistd.h>
#include "vm_util.h"
#include "kselftest.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
uint64_t page_size;
uint64_t pmd_pagesize;
diff --git a/tools/testing/selftests/mm/guard-regions.c b/tools/testing/selftests/mm/guard-regions.c
index 48e8b1539be3..feb50b415f52 100644
--- a/tools/testing/selftests/mm/guard-regions.c
+++ b/tools/testing/selftests/mm/guard-regions.c
@@ -21,7 +21,7 @@
#include <sys/uio.h>
#include <unistd.h>
#include "vm_util.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
#include "../pidfd/pidfd.h"
diff --git a/tools/testing/selftests/mm/thp_settings.c b/tools/testing/selftests/mm/hugepage_settings.c
similarity index 99%
rename from tools/testing/selftests/mm/thp_settings.c
rename to tools/testing/selftests/mm/hugepage_settings.c
index f38ba8a27b30..87ecb309b430 100644
--- a/tools/testing/selftests/mm/thp_settings.c
+++ b/tools/testing/selftests/mm/hugepage_settings.c
@@ -8,7 +8,7 @@
#include <unistd.h>
#include "vm_util.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
#define THP_SYSFS "/sys/kernel/mm/transparent_hugepage/"
#define MAX_SETTINGS_DEPTH 4
diff --git a/tools/testing/selftests/mm/thp_settings.h b/tools/testing/selftests/mm/hugepage_settings.h
similarity index 100%
rename from tools/testing/selftests/mm/thp_settings.h
rename to tools/testing/selftests/mm/hugepage_settings.h
diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c
index fac11b7e7443..df7ecd683c26 100644
--- a/tools/testing/selftests/mm/khugepaged.c
+++ b/tools/testing/selftests/mm/khugepaged.c
@@ -22,7 +22,7 @@
#include "linux/magic.h"
#include "vm_util.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
#define BASE_ADDR ((void *)(1UL << 30))
static unsigned long hpage_pmd_size;
diff --git a/tools/testing/selftests/mm/ksm_tests.c b/tools/testing/selftests/mm/ksm_tests.c
index 752a2c0d06ab..fb355f869401 100644
--- a/tools/testing/selftests/mm/ksm_tests.c
+++ b/tools/testing/selftests/mm/ksm_tests.c
@@ -15,7 +15,7 @@
#include "kselftest.h"
#include <include/vdso/time64.h>
#include "vm_util.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
#define KSM_SYSFS_PATH "/sys/kernel/mm/ksm/"
#define KSM_FP(s) (KSM_SYSFS_PATH s)
diff --git a/tools/testing/selftests/mm/migration.c b/tools/testing/selftests/mm/migration.c
index e3c2f831e15a..ccf42002ce86 100644
--- a/tools/testing/selftests/mm/migration.c
+++ b/tools/testing/selftests/mm/migration.c
@@ -5,7 +5,7 @@
*/
#include "kselftest_harness.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
#include <strings.h>
#include <pthread.h>
diff --git a/tools/testing/selftests/mm/prctl_thp_disable.c b/tools/testing/selftests/mm/prctl_thp_disable.c
index ca27200596a4..d8d9d1de57b8 100644
--- a/tools/testing/selftests/mm/prctl_thp_disable.c
+++ b/tools/testing/selftests/mm/prctl_thp_disable.c
@@ -14,7 +14,7 @@
#include <sys/wait.h>
#include "kselftest_harness.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
#include "vm_util.h"
#ifndef PR_THP_DISABLE_EXCEPT_ADVISED
diff --git a/tools/testing/selftests/mm/soft-dirty.c b/tools/testing/selftests/mm/soft-dirty.c
index bcfcac99b436..c426c4636ef5 100644
--- a/tools/testing/selftests/mm/soft-dirty.c
+++ b/tools/testing/selftests/mm/soft-dirty.c
@@ -9,7 +9,7 @@
#include "kselftest.h"
#include "vm_util.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
#define PAGEMAP_FILE_PATH "/proc/self/pagemap"
#define TEST_ITERATIONS 10000
diff --git a/tools/testing/selftests/mm/split_huge_page_test.c b/tools/testing/selftests/mm/split_huge_page_test.c
index 500d07c4938b..cc99294bdd5a 100644
--- a/tools/testing/selftests/mm/split_huge_page_test.c
+++ b/tools/testing/selftests/mm/split_huge_page_test.c
@@ -21,7 +21,7 @@
#include <time.h>
#include "vm_util.h"
#include "kselftest.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
uint64_t pagesize;
unsigned int pageshift;
diff --git a/tools/testing/selftests/mm/transhuge-stress.c b/tools/testing/selftests/mm/transhuge-stress.c
index 7a9f1035099b..8eb0c5630e7e 100644
--- a/tools/testing/selftests/mm/transhuge-stress.c
+++ b/tools/testing/selftests/mm/transhuge-stress.c
@@ -17,7 +17,7 @@
#include <sys/mman.h>
#include "vm_util.h"
#include "kselftest.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
int backing_fd = -1;
int mmap_flags = MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE;
diff --git a/tools/testing/selftests/mm/uffd-wp-mremap.c b/tools/testing/selftests/mm/uffd-wp-mremap.c
index 516c35d236e1..9d67b11c2f28 100644
--- a/tools/testing/selftests/mm/uffd-wp-mremap.c
+++ b/tools/testing/selftests/mm/uffd-wp-mremap.c
@@ -8,7 +8,7 @@
#include <linux/mman.h>
#include <sys/mman.h>
#include "kselftest.h"
-#include "thp_settings.h"
+#include "hugepage_settings.h"
#include "uffd-common.h"
static int pagemap_fd;
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 22/53] selftests/mm: move HugeTLB helpers to hugepage_settings
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (20 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 21/53] selftests/mm: rename thp_settings.[ch] to hugepage_settings.[ch] Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 23/53] selftests/mm: hugepage_settings: use unsigned long in detect_hugetlb_page_size Mike Rapoport
` (30 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Move library functions that abstract HugeTLB /proc and /sysfs access
from vm_util to hugepage_settings.
This will help creating common helpers that save and restore HugeTLB and
THP settings.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/gup_longterm.c | 1 +
tools/testing/selftests/mm/hmm-tests.c | 2 +-
.../testing/selftests/mm/hugepage_settings.c | 68 +++++++++++++++++++
.../testing/selftests/mm/hugepage_settings.h | 8 +++
tools/testing/selftests/mm/hugetlb-madvise.c | 1 +
tools/testing/selftests/mm/hugetlb-mmap.c | 1 +
tools/testing/selftests/mm/hugetlb-vmemmap.c | 1 +
tools/testing/selftests/mm/hugetlb_dio.c | 1 +
.../selftests/mm/hugetlb_fault_after_madv.c | 1 +
.../selftests/mm/hugetlb_madv_vs_map.c | 1 +
tools/testing/selftests/mm/thuge-gen.c | 1 +
tools/testing/selftests/mm/uffd-common.h | 1 +
.../selftests/mm/va_high_addr_switch.c | 1 +
tools/testing/selftests/mm/vm_util.c | 66 ------------------
tools/testing/selftests/mm/vm_util.h | 3 -
15 files changed, 87 insertions(+), 70 deletions(-)
diff --git a/tools/testing/selftests/mm/gup_longterm.c b/tools/testing/selftests/mm/gup_longterm.c
index f61150d28eb2..ab4eaf4feb7c 100644
--- a/tools/testing/selftests/mm/gup_longterm.c
+++ b/tools/testing/selftests/mm/gup_longterm.c
@@ -29,6 +29,7 @@
#include "../../../../mm/gup_test.h"
#include "kselftest.h"
#include "vm_util.h"
+#include "hugepage_settings.h"
static size_t pagesize;
static int nr_hugetlbsizes;
diff --git a/tools/testing/selftests/mm/hmm-tests.c b/tools/testing/selftests/mm/hmm-tests.c
index 788689497e92..409b11cad4bc 100644
--- a/tools/testing/selftests/mm/hmm-tests.c
+++ b/tools/testing/selftests/mm/hmm-tests.c
@@ -11,6 +11,7 @@
*/
#include "kselftest_harness.h"
+#include "hugepage_settings.h"
#include <errno.h>
#include <fcntl.h>
@@ -27,7 +28,6 @@
#include <sys/ioctl.h>
#include <sys/time.h>
-
/*
* This is a private UAPI to the kernel test module so it isn't exported
* in the usual include/uapi/... directory.
diff --git a/tools/testing/selftests/mm/hugepage_settings.c b/tools/testing/selftests/mm/hugepage_settings.c
index 87ecb309b430..ebaa621c45c6 100644
--- a/tools/testing/selftests/mm/hugepage_settings.c
+++ b/tools/testing/selftests/mm/hugepage_settings.c
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
+#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -396,3 +398,69 @@ bool thp_is_enabled(void)
/* THP is considered enabled if it's either "always" or "madvise" */
return mode == 1 || mode == 3;
}
+
+int detect_hugetlb_page_sizes(size_t sizes[], int max)
+{
+ DIR *dir = opendir("/sys/kernel/mm/hugepages/");
+ int count = 0;
+
+ if (!dir)
+ return 0;
+
+ while (count < max) {
+ struct dirent *entry = readdir(dir);
+ size_t kb;
+
+ if (!entry)
+ break;
+ if (entry->d_type != DT_DIR)
+ continue;
+ if (sscanf(entry->d_name, "hugepages-%zukB", &kb) != 1)
+ continue;
+ sizes[count++] = kb * 1024;
+ ksft_print_msg("[INFO] detected hugetlb page size: %zu KiB\n",
+ kb);
+ }
+ closedir(dir);
+ return count;
+}
+
+unsigned long default_huge_page_size(void)
+{
+ unsigned long hps = 0;
+ char *line = NULL;
+ size_t linelen = 0;
+ FILE *f = fopen("/proc/meminfo", "r");
+
+ if (!f)
+ return 0;
+ while (getline(&line, &linelen, f) > 0) {
+ if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) {
+ hps <<= 10;
+ break;
+ }
+ }
+
+ free(line);
+ fclose(f);
+ return hps;
+}
+
+unsigned long get_free_hugepages(void)
+{
+ unsigned long fhp = 0;
+ char *line = NULL;
+ size_t linelen = 0;
+ FILE *f = fopen("/proc/meminfo", "r");
+
+ if (!f)
+ return fhp;
+ while (getline(&line, &linelen, f) > 0) {
+ if (sscanf(line, "HugePages_Free: %lu", &fhp) == 1)
+ break;
+ }
+
+ free(line);
+ fclose(f);
+ return fhp;
+}
diff --git a/tools/testing/selftests/mm/hugepage_settings.h b/tools/testing/selftests/mm/hugepage_settings.h
index 7748a9009191..320b97e768e8 100644
--- a/tools/testing/selftests/mm/hugepage_settings.h
+++ b/tools/testing/selftests/mm/hugepage_settings.h
@@ -6,6 +6,8 @@
#include <stddef.h>
#include <stdint.h>
+/* Transparent Huge Pages (THP) */
+
enum thp_enabled {
THP_NEVER,
THP_ALWAYS,
@@ -86,4 +88,10 @@ unsigned long thp_shmem_supported_orders(void);
bool thp_available(void);
bool thp_is_enabled(void);
+/* HugeTLB */
+
+int detect_hugetlb_page_sizes(size_t sizes[], int max);
+unsigned long default_huge_page_size(void);
+unsigned long get_free_hugepages(void);
+
#endif /* __THP_SETTINGS_H__ */
diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c
index 4c6c346a3af5..316384d919db 100644
--- a/tools/testing/selftests/mm/hugetlb-madvise.c
+++ b/tools/testing/selftests/mm/hugetlb-madvise.c
@@ -20,6 +20,7 @@
#include <fcntl.h>
#include "vm_util.h"
#include "kselftest.h"
+#include "hugepage_settings.h"
#define MIN_FREE_PAGES 20
#define NR_HUGE_PAGES 10 /* common number of pages to map/allocate */
diff --git a/tools/testing/selftests/mm/hugetlb-mmap.c b/tools/testing/selftests/mm/hugetlb-mmap.c
index 71a444d8b1cb..5be68fbc36dc 100644
--- a/tools/testing/selftests/mm/hugetlb-mmap.c
+++ b/tools/testing/selftests/mm/hugetlb-mmap.c
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include "vm_util.h"
#include "kselftest.h"
+#include "hugepage_settings.h"
#define LENGTH (256UL*1024*1024)
#define PROTECTION (PROT_READ | PROT_WRITE)
diff --git a/tools/testing/selftests/mm/hugetlb-vmemmap.c b/tools/testing/selftests/mm/hugetlb-vmemmap.c
index 485a6978b40f..af5786bebfd1 100644
--- a/tools/testing/selftests/mm/hugetlb-vmemmap.c
+++ b/tools/testing/selftests/mm/hugetlb-vmemmap.c
@@ -11,6 +11,7 @@
#include <sys/mman.h>
#include <fcntl.h>
#include "vm_util.h"
+#include "hugepage_settings.h"
#define PAGE_COMPOUND_HEAD (1UL << 15)
#define PAGE_COMPOUND_TAIL (1UL << 16)
diff --git a/tools/testing/selftests/mm/hugetlb_dio.c b/tools/testing/selftests/mm/hugetlb_dio.c
index 31a054fa8134..81e3f7bc8e76 100644
--- a/tools/testing/selftests/mm/hugetlb_dio.c
+++ b/tools/testing/selftests/mm/hugetlb_dio.c
@@ -20,6 +20,7 @@
#include <sys/syscall.h>
#include "vm_util.h"
#include "kselftest.h"
+#include "hugepage_settings.h"
#ifndef STATX_DIOALIGN
#define STATX_DIOALIGN 0x00002000U
diff --git a/tools/testing/selftests/mm/hugetlb_fault_after_madv.c b/tools/testing/selftests/mm/hugetlb_fault_after_madv.c
index b4b257775b74..abc3904c5268 100644
--- a/tools/testing/selftests/mm/hugetlb_fault_after_madv.c
+++ b/tools/testing/selftests/mm/hugetlb_fault_after_madv.c
@@ -10,6 +10,7 @@
#include "vm_util.h"
#include "kselftest.h"
+#include "hugepage_settings.h"
#define INLOOP_ITER 100
diff --git a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
index c7105c6d319b..ac60b4f18784 100644
--- a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
+++ b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
@@ -25,6 +25,7 @@
#include <unistd.h>
#include "vm_util.h"
+#include "hugepage_settings.h"
#define INLOOP_ITER 100
diff --git a/tools/testing/selftests/mm/thuge-gen.c b/tools/testing/selftests/mm/thuge-gen.c
index 77813d34dcc2..1007bc8aa57c 100644
--- a/tools/testing/selftests/mm/thuge-gen.c
+++ b/tools/testing/selftests/mm/thuge-gen.c
@@ -28,6 +28,7 @@
#include <string.h>
#include "vm_util.h"
#include "kselftest.h"
+#include "hugepage_settings.h"
#if !defined(MAP_HUGETLB)
#define MAP_HUGETLB 0x40000
diff --git a/tools/testing/selftests/mm/uffd-common.h b/tools/testing/selftests/mm/uffd-common.h
index 844a85ab31eb..6c5aca9cb63e 100644
--- a/tools/testing/selftests/mm/uffd-common.h
+++ b/tools/testing/selftests/mm/uffd-common.h
@@ -37,6 +37,7 @@
#include "kselftest.h"
#include "vm_util.h"
+#include "hugepage_settings.h"
#define UFFD_FLAGS (O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY)
diff --git a/tools/testing/selftests/mm/va_high_addr_switch.c b/tools/testing/selftests/mm/va_high_addr_switch.c
index 5741fd057640..d42ad50eb2d3 100644
--- a/tools/testing/selftests/mm/va_high_addr_switch.c
+++ b/tools/testing/selftests/mm/va_high_addr_switch.c
@@ -11,6 +11,7 @@
#include "vm_util.h"
#include "kselftest.h"
+#include "hugepage_settings.h"
/*
* The hint addr value is used to allocate addresses
diff --git a/tools/testing/selftests/mm/vm_util.c b/tools/testing/selftests/mm/vm_util.c
index db94564f4431..e62e2a473123 100644
--- a/tools/testing/selftests/mm/vm_util.c
+++ b/tools/testing/selftests/mm/vm_util.c
@@ -291,53 +291,6 @@ int64_t allocate_transhuge(void *ptr, int pagemap_fd)
return -1;
}
-unsigned long default_huge_page_size(void)
-{
- unsigned long hps = 0;
- char *line = NULL;
- size_t linelen = 0;
- FILE *f = fopen("/proc/meminfo", "r");
-
- if (!f)
- return 0;
- while (getline(&line, &linelen, f) > 0) {
- if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) {
- hps <<= 10;
- break;
- }
- }
-
- free(line);
- fclose(f);
- return hps;
-}
-
-int detect_hugetlb_page_sizes(size_t sizes[], int max)
-{
- DIR *dir = opendir("/sys/kernel/mm/hugepages/");
- int count = 0;
-
- if (!dir)
- return 0;
-
- while (count < max) {
- struct dirent *entry = readdir(dir);
- size_t kb;
-
- if (!entry)
- break;
- if (entry->d_type != DT_DIR)
- continue;
- if (sscanf(entry->d_name, "hugepages-%zukB", &kb) != 1)
- continue;
- sizes[count++] = kb * 1024;
- ksft_print_msg("[INFO] detected hugetlb page size: %zu KiB\n",
- kb);
- }
- closedir(dir);
- return count;
-}
-
int pageflags_get(unsigned long pfn, int kpageflags_fd, uint64_t *flags)
{
size_t count;
@@ -396,25 +349,6 @@ int uffd_unregister(int uffd, void *addr, uint64_t len)
return ret;
}
-unsigned long get_free_hugepages(void)
-{
- unsigned long fhp = 0;
- char *line = NULL;
- size_t linelen = 0;
- FILE *f = fopen("/proc/meminfo", "r");
-
- if (!f)
- return fhp;
- while (getline(&line, &linelen, f) > 0) {
- if (sscanf(line, "HugePages_Free: %lu", &fhp) == 1)
- break;
- }
-
- free(line);
- fclose(f);
- return fhp;
-}
-
static bool check_vmflag(void *addr, const char *flag)
{
char buffer[MAX_LINE_LENGTH];
diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h
index 1a07305ceff4..195bf2e26792 100644
--- a/tools/testing/selftests/mm/vm_util.h
+++ b/tools/testing/selftests/mm/vm_util.h
@@ -94,8 +94,6 @@ bool check_huge_anon(void *addr, int nr_hpages, uint64_t hpage_size);
bool check_huge_file(void *addr, int nr_hpages, uint64_t hpage_size);
bool check_huge_shmem(void *addr, int nr_hpages, uint64_t hpage_size);
int64_t allocate_transhuge(void *ptr, int pagemap_fd);
-unsigned long default_huge_page_size(void);
-int detect_hugetlb_page_sizes(size_t sizes[], int max);
int pageflags_get(unsigned long pfn, int kpageflags_fd, uint64_t *flags);
int uffd_register(int uffd, void *addr, uint64_t len,
@@ -103,7 +101,6 @@ int uffd_register(int uffd, void *addr, uint64_t len,
int uffd_unregister(int uffd, void *addr, uint64_t len);
int uffd_register_with_ioctls(int uffd, void *addr, uint64_t len,
bool miss, bool wp, bool minor, uint64_t *ioctls);
-unsigned long get_free_hugepages(void);
bool check_vmflag_io(void *addr);
bool check_vmflag_pfnmap(void *addr);
bool check_vmflag_guard(void *addr);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 23/53] selftests/mm: hugepage_settings: use unsigned long in detect_hugetlb_page_size
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (21 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 22/53] selftests/mm: move HugeTLB helpers to hugepage_settings Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 24/53] selftests/mm: hugepage_settings: add APIs to get and set nr_hugepages Mike Rapoport
` (29 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
... instead of size_t to avoid type mismatch in 32 and 64 bit builds.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugepage_settings.c | 2 +-
tools/testing/selftests/mm/hugepage_settings.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/mm/hugepage_settings.c b/tools/testing/selftests/mm/hugepage_settings.c
index ebaa621c45c6..8f563315b1fc 100644
--- a/tools/testing/selftests/mm/hugepage_settings.c
+++ b/tools/testing/selftests/mm/hugepage_settings.c
@@ -399,7 +399,7 @@ bool thp_is_enabled(void)
return mode == 1 || mode == 3;
}
-int detect_hugetlb_page_sizes(size_t sizes[], int max)
+int detect_hugetlb_page_sizes(unsigned long sizes[], int max)
{
DIR *dir = opendir("/sys/kernel/mm/hugepages/");
int count = 0;
diff --git a/tools/testing/selftests/mm/hugepage_settings.h b/tools/testing/selftests/mm/hugepage_settings.h
index 320b97e768e8..9357d07e6c1b 100644
--- a/tools/testing/selftests/mm/hugepage_settings.h
+++ b/tools/testing/selftests/mm/hugepage_settings.h
@@ -90,7 +90,7 @@ bool thp_is_enabled(void);
/* HugeTLB */
-int detect_hugetlb_page_sizes(size_t sizes[], int max);
+int detect_hugetlb_page_sizes(unsigned long sizes[], int max);
unsigned long default_huge_page_size(void);
unsigned long get_free_hugepages(void);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 24/53] selftests/mm: hugepage_settings: add APIs to get and set nr_hugepages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (22 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 23/53] selftests/mm: hugepage_settings: use unsigned long in detect_hugetlb_page_size Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 25/53] selftests/mm: hugepage_settings: rename get_free_hugepages() Mike Rapoport
` (28 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Add APIs that allow reading and writing of
/sys/kernel/mm/hugepages/hugepages-NkB/nr_hugepages
to detect and change the amount of HugeTLB pages of different sizes.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
.../testing/selftests/mm/hugepage_settings.c | 25 +++++++++++++++++++
.../testing/selftests/mm/hugepage_settings.h | 23 +++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/tools/testing/selftests/mm/hugepage_settings.c b/tools/testing/selftests/mm/hugepage_settings.c
index 8f563315b1fc..5961229b9931 100644
--- a/tools/testing/selftests/mm/hugepage_settings.c
+++ b/tools/testing/selftests/mm/hugepage_settings.c
@@ -464,3 +464,28 @@ unsigned long get_free_hugepages(void)
fclose(f);
return fhp;
}
+
+static void hugetlb_sysfs_path(char *buf, size_t buflen,
+ unsigned long size, const char *attr)
+{
+ snprintf(buf, buflen, "/sys/kernel/mm/hugepages/hugepages-%lukB/%s",
+ size / 1024, attr);
+}
+
+unsigned long hugetlb_nr_pages(unsigned long size)
+{
+ char path[PATH_MAX];
+
+ hugetlb_sysfs_path(path, sizeof(path), size, "nr_hugepages");
+
+ return read_num(path);
+}
+
+void hugetlb_set_nr_pages(unsigned long size, unsigned long nr)
+{
+ char path[PATH_MAX];
+
+ hugetlb_sysfs_path(path, sizeof(path), size, "nr_hugepages");
+
+ write_num(path, nr);
+}
diff --git a/tools/testing/selftests/mm/hugepage_settings.h b/tools/testing/selftests/mm/hugepage_settings.h
index 9357d07e6c1b..d6f41a45e8ee 100644
--- a/tools/testing/selftests/mm/hugepage_settings.h
+++ b/tools/testing/selftests/mm/hugepage_settings.h
@@ -94,4 +94,27 @@ int detect_hugetlb_page_sizes(unsigned long sizes[], int max);
unsigned long default_huge_page_size(void);
unsigned long get_free_hugepages(void);
+unsigned long hugetlb_nr_pages(unsigned long size);
+void hugetlb_set_nr_pages(unsigned long size, unsigned long nr);
+
+static inline unsigned long hugetlb_nr_default_pages(void)
+{
+ unsigned long size = default_huge_page_size();
+
+ if (!size)
+ return 0;
+
+ return hugetlb_nr_pages(size);
+}
+
+static inline void hugetlb_set_nr_default_pages(unsigned long nr)
+{
+ unsigned long size = default_huge_page_size();
+
+ if (!size)
+ return;
+
+ hugetlb_set_nr_pages(size, nr);
+}
+
#endif /* __THP_SETTINGS_H__ */
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 25/53] selftests/mm: hugepage_settings: rename get_free_hugepages()
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (23 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 24/53] selftests/mm: hugepage_settings: add APIs to get and set nr_hugepages Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 26/53] selftests/mm: hugepage_settings: add APIs for HugeTLB setup and teardown Mike Rapoport
` (27 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
... to hugetlb_free_default_hugepages() for consistency with
hugetlb_nr_default_pages().
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
.../testing/selftests/mm/hugepage_settings.c | 28 ++++++-------------
.../testing/selftests/mm/hugepage_settings.h | 12 +++++++-
tools/testing/selftests/mm/hugetlb-madvise.c | 4 +--
tools/testing/selftests/mm/hugetlb_dio.c | 6 ++--
.../selftests/mm/hugetlb_fault_after_madv.c | 2 +-
.../selftests/mm/hugetlb_madv_vs_map.c | 2 +-
tools/testing/selftests/mm/uffd-stress.c | 2 +-
7 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/tools/testing/selftests/mm/hugepage_settings.c b/tools/testing/selftests/mm/hugepage_settings.c
index 5961229b9931..4ae7332b5e1b 100644
--- a/tools/testing/selftests/mm/hugepage_settings.c
+++ b/tools/testing/selftests/mm/hugepage_settings.c
@@ -446,25 +446,6 @@ unsigned long default_huge_page_size(void)
return hps;
}
-unsigned long get_free_hugepages(void)
-{
- unsigned long fhp = 0;
- char *line = NULL;
- size_t linelen = 0;
- FILE *f = fopen("/proc/meminfo", "r");
-
- if (!f)
- return fhp;
- while (getline(&line, &linelen, f) > 0) {
- if (sscanf(line, "HugePages_Free: %lu", &fhp) == 1)
- break;
- }
-
- free(line);
- fclose(f);
- return fhp;
-}
-
static void hugetlb_sysfs_path(char *buf, size_t buflen,
unsigned long size, const char *attr)
{
@@ -489,3 +470,12 @@ void hugetlb_set_nr_pages(unsigned long size, unsigned long nr)
write_num(path, nr);
}
+
+unsigned long hugetlb_free_pages(unsigned long size)
+{
+ char path[PATH_MAX];
+
+ hugetlb_sysfs_path(path, sizeof(path), size, "free_hugepages");
+
+ return read_num(path);
+}
diff --git a/tools/testing/selftests/mm/hugepage_settings.h b/tools/testing/selftests/mm/hugepage_settings.h
index d6f41a45e8ee..57fbf2f57e13 100644
--- a/tools/testing/selftests/mm/hugepage_settings.h
+++ b/tools/testing/selftests/mm/hugepage_settings.h
@@ -92,10 +92,10 @@ bool thp_is_enabled(void);
int detect_hugetlb_page_sizes(unsigned long sizes[], int max);
unsigned long default_huge_page_size(void);
-unsigned long get_free_hugepages(void);
unsigned long hugetlb_nr_pages(unsigned long size);
void hugetlb_set_nr_pages(unsigned long size, unsigned long nr);
+unsigned long hugetlb_free_pages(unsigned long size);
static inline unsigned long hugetlb_nr_default_pages(void)
{
@@ -117,4 +117,14 @@ static inline void hugetlb_set_nr_default_pages(unsigned long nr)
hugetlb_set_nr_pages(size, nr);
}
+static inline unsigned long hugetlb_free_default_pages(void)
+{
+ unsigned long size = default_huge_page_size();
+
+ if (!size)
+ return 0;
+
+ return hugetlb_free_pages(size);
+}
+
#endif /* __THP_SETTINGS_H__ */
diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c
index 316384d919db..3c08eb6db6a2 100644
--- a/tools/testing/selftests/mm/hugetlb-madvise.c
+++ b/tools/testing/selftests/mm/hugetlb-madvise.c
@@ -27,7 +27,7 @@
#define validate_free_pages(exp_free) \
do { \
- unsigned long fhp = get_free_hugepages(); \
+ unsigned long fhp = hugetlb_free_default_pages(); \
if (fhp != (exp_free)) \
ksft_exit_fail_msg("Unexpected number of free " \
"huge pages %ld, expected %ld line %d\n", \
@@ -68,7 +68,7 @@ int main(int argc, char **argv)
if (!base_page_size)
ksft_exit_fail_msg("Unable to determine base page size\n");
- free_hugepages = get_free_hugepages();
+ free_hugepages = hugetlb_free_default_pages();
if (free_hugepages < MIN_FREE_PAGES)
ksft_exit_skip("Not enough free huge pages (have %lu, need %d)\n", free_hugepages, MIN_FREE_PAGES);
diff --git a/tools/testing/selftests/mm/hugetlb_dio.c b/tools/testing/selftests/mm/hugetlb_dio.c
index 81e3f7bc8e76..47019433ddaf 100644
--- a/tools/testing/selftests/mm/hugetlb_dio.c
+++ b/tools/testing/selftests/mm/hugetlb_dio.c
@@ -93,7 +93,7 @@ static void run_dio_using_hugetlb(int fd, unsigned int start_off,
ksft_exit_fail_perror("lseek failed\n");
/* Get the free huge pages before allocation */
- free_hpage_b = get_free_hugepages();
+ free_hpage_b = hugetlb_free_default_pages();
if (free_hpage_b == 0) {
close(fd);
ksft_exit_skip("No free hugepage, exiting!\n");
@@ -121,7 +121,7 @@ static void run_dio_using_hugetlb(int fd, unsigned int start_off,
munmap(orig_buffer, h_pagesize);
/* Get the free huge pages after unmap*/
- free_hpage_a = get_free_hugepages();
+ free_hpage_a = hugetlb_free_default_pages();
ksft_print_msg("No. Free pages before allocation : %d\n", free_hpage_b);
ksft_print_msg("No. Free pages after munmap : %d\n", free_hpage_a);
@@ -142,7 +142,7 @@ int main(void)
ksft_print_header();
/* Check if huge pages are free */
- if (!get_free_hugepages())
+ if (!hugetlb_free_default_pages())
ksft_exit_skip("No free hugepage, exiting\n");
fd = open("/tmp", O_TMPFILE | O_RDWR | O_DIRECT, 0664);
diff --git a/tools/testing/selftests/mm/hugetlb_fault_after_madv.c b/tools/testing/selftests/mm/hugetlb_fault_after_madv.c
index abc3904c5268..c718dd065d53 100644
--- a/tools/testing/selftests/mm/hugetlb_fault_after_madv.c
+++ b/tools/testing/selftests/mm/hugetlb_fault_after_madv.c
@@ -78,7 +78,7 @@ int main(void)
ksft_print_msg("[INFO] detected default hugetlb page size: %zu KiB\n",
huge_page_size / 1024);
- free_hugepages = get_free_hugepages();
+ free_hugepages = hugetlb_free_default_pages();
if (free_hugepages != 1) {
ksft_exit_skip("This test needs one and only one page to execute. Got %lu\n",
free_hugepages);
diff --git a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
index ac60b4f18784..dfbd71a7f709 100644
--- a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
+++ b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
@@ -89,7 +89,7 @@ int main(void)
ksft_print_header();
ksft_set_plan(1);
- free_hugepages = get_free_hugepages();
+ free_hugepages = hugetlb_free_default_pages();
if (free_hugepages != 1)
ksft_exit_skip("This test needs one and only one page to execute. Got %lu\n",
diff --git a/tools/testing/selftests/mm/uffd-stress.c b/tools/testing/selftests/mm/uffd-stress.c
index e92a85463eb1..7e37cf3d27f6 100644
--- a/tools/testing/selftests/mm/uffd-stress.c
+++ b/tools/testing/selftests/mm/uffd-stress.c
@@ -480,7 +480,7 @@ int main(int argc, char **argv)
* for racy extra reservation of hugepages.
*/
if (gopts->test_type == TEST_HUGETLB &&
- get_free_hugepages() < 2 * (bytes / gopts->page_size) + gopts->nr_parallel - 1)
+ hugetlb_free_default_pages() < 2 * (bytes / gopts->page_size) + gopts->nr_parallel - 1)
ksft_exit_skip("Skipping userfaultfd... not enough hugepages\n");
gopts->nr_pages_per_cpu = bytes / gopts->page_size / gopts->nr_parallel;
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 26/53] selftests/mm: hugepage_settings: add APIs for HugeTLB setup and teardown
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (24 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 25/53] selftests/mm: hugepage_settings: rename get_free_hugepages() Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 27/53] selftests/mm: move read_file(), read_num() and write_num() to vm_util Mike Rapoport
` (26 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
A lot of tests require free HugeTLB pages. Some need just a few default
huge pages, some need a certain amount of memory available as HugeTLB, and
some just skip lots of tests if huge pages of all supported sizes are not
available.
This all resulted in a huge mess in run_vmtests.sh that sets up some huge
pages, adjusts them later and restores some of the settings if the stars
align.
Add APIs that allow saving the state of HugeTLB and setting up the desired
amount of HugeTLB pages.
Saving the state also registers atexit() callback and signal handler that
will ensure restoration of HugeTLB state.
Since many tests use both HugeTLB and THP, the atexit() callbacks and
signal handler are restoring both.
For kselftest_harness tests that run fixture setups and test in child
processes add a constructor that will save and restore settings in the main
process.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
.../testing/selftests/mm/hugepage_settings.c | 176 +++++++++++++++---
.../testing/selftests/mm/hugepage_settings.h | 30 ++-
2 files changed, 181 insertions(+), 25 deletions(-)
diff --git a/tools/testing/selftests/mm/hugepage_settings.c b/tools/testing/selftests/mm/hugepage_settings.c
index 4ae7332b5e1b..3eef87e812ba 100644
--- a/tools/testing/selftests/mm/hugepage_settings.c
+++ b/tools/testing/selftests/mm/hugepage_settings.c
@@ -306,31 +306,12 @@ void thp_restore_settings(void)
thp_write_settings(&saved_settings);
}
-static void thp_restore_settings_atexit(void)
+static void __thp_save_settings(void)
{
- thp_restore_settings();
-}
-
-static void thp_restore_settings_sighandler(int sig)
-{
- /* exit() will invoke the thp_restore_settings_atexit handler. */
- exit(KSFT_FAIL);
-}
+ if (!thp_available())
+ return;
-void thp_save_settings(void)
-{
thp_read_settings(&saved_settings);
-
- /*
- * setup exit hooks to make sure THP settings are restored on graceful
- * and error exits and signals
- */
- atexit(thp_restore_settings_atexit);
- signal(SIGTERM, thp_restore_settings_sighandler);
- signal(SIGINT, thp_restore_settings_sighandler);
- signal(SIGHUP, thp_restore_settings_sighandler);
- signal(SIGQUIT, thp_restore_settings_sighandler);
-
thp_settings_saved = true;
}
@@ -399,11 +380,31 @@ bool thp_is_enabled(void)
return mode == 1 || mode == 3;
}
+#define HUGETLB_MAX_NR_PAGESIZES 10
+struct hugetlb_settings {
+ unsigned long free_hugepages[HUGETLB_MAX_NR_PAGESIZES];
+ unsigned long nr_hugepages[HUGETLB_MAX_NR_PAGESIZES];
+ unsigned long sizes[HUGETLB_MAX_NR_PAGESIZES];
+ unsigned long default_size;
+ int nr_sizes;
+};
+
+static struct hugetlb_settings hugetlb_saved_settings;
+bool hugetlb_settings_saved;
+
int detect_hugetlb_page_sizes(unsigned long sizes[], int max)
{
- DIR *dir = opendir("/sys/kernel/mm/hugepages/");
+ static struct hugetlb_settings *settings = &hugetlb_saved_settings;
+ DIR *dir;
int count = 0;
+ if (settings->nr_sizes) {
+ for (count = 0; count < settings->nr_sizes; count++)
+ sizes[count] = settings->sizes[count];
+ return settings->nr_sizes;
+ }
+
+ dir = opendir("/sys/kernel/mm/hugepages/");
if (!dir)
return 0;
@@ -427,11 +428,16 @@ int detect_hugetlb_page_sizes(unsigned long sizes[], int max)
unsigned long default_huge_page_size(void)
{
+ static struct hugetlb_settings *settings = &hugetlb_saved_settings;
unsigned long hps = 0;
char *line = NULL;
size_t linelen = 0;
- FILE *f = fopen("/proc/meminfo", "r");
+ FILE *f;
+
+ if (settings->default_size)
+ return settings->default_size;
+ f = fopen("/proc/meminfo", "r");
if (!f)
return 0;
while (getline(&line, &linelen, f) > 0) {
@@ -479,3 +485,125 @@ unsigned long hugetlb_free_pages(unsigned long size)
return read_num(path);
}
+
+bool hugetlb_setup_default(unsigned long nr)
+{
+ unsigned long size;
+
+ hugetlb_save_settings();
+
+ size = default_huge_page_size();
+ hugetlb_set_nr_pages(size, nr);
+
+ return hugetlb_free_pages(size) == nr;
+}
+
+unsigned long hugetlb_setup(unsigned long nr, unsigned long sizes[],
+ int max)
+{
+ unsigned long enabled[10];
+ int nr_sizes = 0;
+ int nr_enabled;
+
+ nr_enabled = detect_hugetlb_page_sizes(enabled, ARRAY_SIZE(enabled));
+ if (!nr_enabled)
+ return 0;
+
+ if (nr_enabled > max) {
+ ksft_print_msg("detected %d huge page sizes, will only test %d\n", nr_enabled, max);
+ nr_enabled = max;
+ }
+
+ /* If HugeTLB is supported, request 2 HugeTLB pages of every size. */
+ for (int i = 0; i < nr_enabled; i++) {
+ hugetlb_set_nr_pages(enabled[i], nr);
+ if (hugetlb_free_pages(enabled[i]) < nr)
+ continue;
+
+ sizes[nr_sizes++] = enabled[i];
+ }
+
+ return nr_sizes;
+}
+
+static void __hugetlb_save_settings(void)
+{
+ struct hugetlb_settings *settings = &hugetlb_saved_settings;
+ int nr_sizes;
+
+ settings->default_size = default_huge_page_size();
+ if (!settings->default_size)
+ return;
+
+ nr_sizes = detect_hugetlb_page_sizes(settings->sizes,
+ HUGETLB_MAX_NR_PAGESIZES);
+ if (!nr_sizes) {
+ settings->default_size = 0;
+ return;
+ }
+
+ for (int i = 0; i < nr_sizes; i++) {
+ unsigned long sz = settings->sizes[i];
+
+ if (!sz)
+ continue;
+
+ settings->free_hugepages[i] = hugetlb_free_pages(sz);
+ settings->nr_hugepages[i] = hugetlb_nr_pages(sz);
+ }
+
+ settings->nr_sizes = nr_sizes;
+ hugetlb_settings_saved = true;
+}
+
+void hugetlb_restore_settings(void)
+{
+ struct hugetlb_settings *settings = &hugetlb_saved_settings;
+
+ if (!hugetlb_settings_saved || !settings->default_size)
+ return;
+
+ for (int i = 0; i < HUGETLB_MAX_NR_PAGESIZES; i++) {
+ unsigned long sz = settings->sizes[i];
+
+ if (!sz)
+ continue;
+
+ hugetlb_set_nr_pages(sz, settings->nr_hugepages[i]);
+ }
+}
+
+static void hugepage_restore_settings_atexit(void)
+{
+ if (thp_settings_saved)
+ thp_restore_settings();
+ if (hugetlb_settings_saved)
+ hugetlb_restore_settings();
+}
+
+static void hugepage_restore_settings_sighandler(int sig)
+{
+ /* exit() will invoke the hugetlb_restore_settings_atexit handler. */
+ exit(KSFT_FAIL);
+}
+
+void hugepage_save_settings(bool thp, bool hugetlb)
+{
+ if (!thp && !hugetlb)
+ return;
+
+ if (thp)
+ __thp_save_settings();
+ if (hugetlb)
+ __hugetlb_save_settings();
+
+ /*
+ * setup exit hooks to make sure THP settings are restored on graceful
+ * and error exits and signals
+ */
+ atexit(hugepage_restore_settings_atexit);
+ signal(SIGTERM, hugepage_restore_settings_sighandler);
+ signal(SIGINT, hugepage_restore_settings_sighandler);
+ signal(SIGHUP, hugepage_restore_settings_sighandler);
+ signal(SIGQUIT, hugepage_restore_settings_sighandler);
+}
diff --git a/tools/testing/selftests/mm/hugepage_settings.h b/tools/testing/selftests/mm/hugepage_settings.h
index 57fbf2f57e13..d6a1b4e5f734 100644
--- a/tools/testing/selftests/mm/hugepage_settings.h
+++ b/tools/testing/selftests/mm/hugepage_settings.h
@@ -6,6 +6,8 @@
#include <stddef.h>
#include <stdint.h>
+void hugepage_save_settings(bool thp, bool hugetlb);
+
/* Transparent Huge Pages (THP) */
enum thp_enabled {
@@ -79,7 +81,11 @@ struct thp_settings *thp_current_settings(void);
void thp_push_settings(struct thp_settings *settings);
void thp_pop_settings(void);
void thp_restore_settings(void);
-void thp_save_settings(void);
+
+static inline void thp_save_settings(void)
+{
+ hugepage_save_settings(/* thp = */ true, /* hugetlb = */ false);
+}
void thp_set_read_ahead_path(char *path);
unsigned long thp_supported_orders(void);
@@ -97,6 +103,13 @@ unsigned long hugetlb_nr_pages(unsigned long size);
void hugetlb_set_nr_pages(unsigned long size, unsigned long nr);
unsigned long hugetlb_free_pages(unsigned long size);
+static inline void hugetlb_save_settings(void)
+{
+ hugepage_save_settings(/* thp = */ false, /* hugetlb = */ true);
+}
+
+void hugetlb_restore_settings(void);
+
static inline unsigned long hugetlb_nr_default_pages(void)
{
unsigned long size = default_huge_page_size();
@@ -127,4 +140,19 @@ static inline unsigned long hugetlb_free_default_pages(void)
return hugetlb_free_pages(size);
}
+static inline bool hugetlb_available(void)
+{
+ return default_huge_page_size() != 0;
+}
+
+bool hugetlb_setup_default(unsigned long nr);
+unsigned long hugetlb_setup(unsigned long nr, unsigned long sizes[],
+ int max);
+
+#define HUGETLB_SETUP_DEFAULT_PAGES(nr_pages) \
+static void __attribute__((constructor)) __hugetlb_setup_default(void) \
+{ \
+ hugetlb_setup_default((nr_pages)); \
+}
+
#endif /* __THP_SETTINGS_H__ */
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 27/53] selftests/mm: move read_file(), read_num() and write_num() to vm_util
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (25 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 26/53] selftests/mm: hugepage_settings: add APIs for HugeTLB setup and teardown Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 28/53] selftests/mm: vm_util: add helpers to set and restore shm limits Mike Rapoport
` (25 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
These are useful helpers for writing and reading sysfs and proc files.
Make them available to the tests that don't use thp_settings.
While on it make write_num() use "%lu" instead of "%ld" to match
'unsigned long num' argument type.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
.../testing/selftests/mm/hugepage_settings.c | 41 -------------------
.../testing/selftests/mm/hugepage_settings.h | 4 --
tools/testing/selftests/mm/vm_util.c | 39 ++++++++++++++++++
tools/testing/selftests/mm/vm_util.h | 3 ++
4 files changed, 42 insertions(+), 45 deletions(-)
diff --git a/tools/testing/selftests/mm/hugepage_settings.c b/tools/testing/selftests/mm/hugepage_settings.c
index 3eef87e812ba..339802ecc8e4 100644
--- a/tools/testing/selftests/mm/hugepage_settings.c
+++ b/tools/testing/selftests/mm/hugepage_settings.c
@@ -48,47 +48,6 @@ static const char * const shmem_enabled_strings[] = {
NULL
};
-int read_file(const char *path, char *buf, size_t buflen)
-{
- int fd;
- ssize_t numread;
-
- fd = open(path, O_RDONLY);
- if (fd == -1)
- return 0;
-
- numread = read(fd, buf, buflen - 1);
- if (numread < 1) {
- close(fd);
- return 0;
- }
-
- buf[numread] = '\0';
- close(fd);
-
- return (unsigned int) numread;
-}
-
-unsigned long read_num(const char *path)
-{
- char buf[21];
-
- if (read_file(path, buf, sizeof(buf)) < 0) {
- perror("read_file()");
- exit(EXIT_FAILURE);
- }
-
- return strtoul(buf, NULL, 10);
-}
-
-void write_num(const char *path, unsigned long num)
-{
- char buf[21];
-
- sprintf(buf, "%ld", num);
- write_file(path, buf, strlen(buf) + 1);
-}
-
int thp_read_string(const char *name, const char * const strings[])
{
char path[PATH_MAX];
diff --git a/tools/testing/selftests/mm/hugepage_settings.h b/tools/testing/selftests/mm/hugepage_settings.h
index d6a1b4e5f734..3d1a4f18be30 100644
--- a/tools/testing/selftests/mm/hugepage_settings.h
+++ b/tools/testing/selftests/mm/hugepage_settings.h
@@ -66,10 +66,6 @@ struct thp_settings {
struct shmem_hugepages_settings shmem_hugepages[NR_ORDERS];
};
-int read_file(const char *path, char *buf, size_t buflen);
-unsigned long read_num(const char *path);
-void write_num(const char *path, unsigned long num);
-
int thp_read_string(const char *name, const char * const strings[]);
void thp_write_string(const char *name, const char *val);
unsigned long thp_read_num(const char *name);
diff --git a/tools/testing/selftests/mm/vm_util.c b/tools/testing/selftests/mm/vm_util.c
index e62e2a473123..752566f75c0b 100644
--- a/tools/testing/selftests/mm/vm_util.c
+++ b/tools/testing/selftests/mm/vm_util.c
@@ -699,6 +699,27 @@ int unpoison_memory(unsigned long pfn)
return ret > 0 ? 0 : -errno;
}
+int read_file(const char *path, char *buf, size_t buflen)
+{
+ int fd;
+ ssize_t numread;
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return 0;
+
+ numread = read(fd, buf, buflen - 1);
+ if (numread < 1) {
+ close(fd);
+ return 0;
+ }
+
+ buf[numread] = '\0';
+ close(fd);
+
+ return (unsigned int) numread;
+}
+
void write_file(const char *path, const char *buf, size_t buflen)
{
int fd, saved_errno;
@@ -722,3 +743,21 @@ void write_file(const char *path, const char *buf, size_t buflen)
ksft_exit_fail_msg("%s write(%.*s) is truncated, expected %zu bytes, got %zd bytes\n",
path, (int)(buflen - 1), buf, buflen - 1, numwritten);
}
+
+unsigned long read_num(const char *path)
+{
+ char buf[21];
+
+ if (read_file(path, buf, sizeof(buf)) < 0)
+ ksft_exit_fail_perror("read_file()");
+
+ return strtoul(buf, NULL, 10);
+}
+
+void write_num(const char *path, unsigned long num)
+{
+ char buf[21];
+
+ sprintf(buf, "%lu", num);
+ write_file(path, buf, strlen(buf) + 1);
+}
diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h
index 195bf2e26792..5fc9707f6b9a 100644
--- a/tools/testing/selftests/mm/vm_util.h
+++ b/tools/testing/selftests/mm/vm_util.h
@@ -165,3 +165,6 @@ int unpoison_memory(unsigned long pfn);
#define PAGEMAP_PFN(ent) ((ent) & ((1ull << 55) - 1))
void write_file(const char *path, const char *buf, size_t buflen);
+int read_file(const char *path, char *buf, size_t buflen);
+unsigned long read_num(const char *path);
+void write_num(const char *path, unsigned long num);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 28/53] selftests/mm: vm_util: add helpers to set and restore shm limits
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (26 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 27/53] selftests/mm: move read_file(), read_num() and write_num() to vm_util Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 29/53] selftests/mm: compaction_test: use HugeTLB helpers Mike Rapoport
` (24 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugetlb-shm and thuge-gen tests require that limits defined by
/proc/sys/kernel/{shmmax,shmall} should be higher than certain values.
Add helpers that allow setting these limits and restoring their settings on
a test exit.
They will be used later in hugetlb-shm and thuge-gen.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/vm_util.c | 28 ++++++++++++++++++++++++++++
tools/testing/selftests/mm/vm_util.h | 9 +++++++++
2 files changed, 37 insertions(+)
diff --git a/tools/testing/selftests/mm/vm_util.c b/tools/testing/selftests/mm/vm_util.c
index 752566f75c0b..5a89c2d903be 100644
--- a/tools/testing/selftests/mm/vm_util.c
+++ b/tools/testing/selftests/mm/vm_util.c
@@ -761,3 +761,31 @@ void write_num(const char *path, unsigned long num)
sprintf(buf, "%lu", num);
write_file(path, buf, strlen(buf) + 1);
}
+
+static unsigned long shmall, shmmax;
+
+void __shm_limits_restore(void)
+{
+ if (shmmax)
+ write_num("/proc/sys/kernel/shmmax", shmmax);
+ if (shmall)
+ write_num("/proc/sys/kernel/shmall", shmall);
+}
+
+void shm_limits_prepare(unsigned long length)
+{
+ unsigned long nr = length / psize();
+ unsigned long val;
+
+ val = read_num("/proc/sys/kernel/shmmax");
+ if (val < length) {
+ write_num("/proc/sys/kernel/shmmax", length);
+ shmmax = val;
+ }
+
+ val = read_num("/proc/sys/kernel/shmall");
+ if (val < nr) {
+ write_num("/proc/sys/kernel/shmall", nr);
+ shmall = val;
+ }
+}
diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h
index 5fc9707f6b9a..ea8fc8fdf0eb 100644
--- a/tools/testing/selftests/mm/vm_util.h
+++ b/tools/testing/selftests/mm/vm_util.h
@@ -168,3 +168,12 @@ void write_file(const char *path, const char *buf, size_t buflen);
int read_file(const char *path, char *buf, size_t buflen);
unsigned long read_num(const char *path);
void write_num(const char *path, unsigned long num);
+
+void shm_limits_prepare(unsigned long length);
+void __shm_limits_restore(void);
+
+#define SHM_LIMITS_RESTORE() \
+static void __attribute__((destructor)) shm_limits_restore(void) \
+{ \
+ __shm_limits_restore(); \
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 29/53] selftests/mm: compaction_test: use HugeTLB helpers ...
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (27 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 28/53] selftests/mm: vm_util: add helpers to set and restore shm limits Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 30/53] selftests/mm: cow: add setup of HugeTLB pages Mike Rapoport
` (23 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
... instead of open coded access of HugeTLB parameters via /proc.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/compaction_test.c | 113 +++----------------
1 file changed, 17 insertions(+), 96 deletions(-)
diff --git a/tools/testing/selftests/mm/compaction_test.c b/tools/testing/selftests/mm/compaction_test.c
index 30209c40b697..962a50c3d66f 100644
--- a/tools/testing/selftests/mm/compaction_test.c
+++ b/tools/testing/selftests/mm/compaction_test.c
@@ -17,6 +17,7 @@
#include <string.h>
#include "kselftest.h"
+#include "hugepage_settings.h"
#define MAP_SIZE_MB 100
#define MAP_SIZE (MAP_SIZE_MB * 1024 * 1024)
@@ -82,75 +83,33 @@ int prereq(void)
return -1;
}
-int check_compaction(unsigned long mem_free, unsigned long hugepage_size,
- unsigned long initial_nr_hugepages)
+int check_compaction(unsigned long mem_free, unsigned long hugepage_size)
{
- unsigned long nr_hugepages_ul;
- int fd, ret = -1;
+ unsigned long nr_hugepages;
int compaction_index = 0;
- char nr_hugepages[20] = {0};
- char init_nr_hugepages[24] = {0};
- char target_nr_hugepages[24] = {0};
- int slen;
-
- snprintf(init_nr_hugepages, sizeof(init_nr_hugepages),
- "%lu", initial_nr_hugepages);
+ int ret = -1;
/* We want to test with 80% of available memory. Else, OOM killer comes
in to play */
mem_free = mem_free * 0.8;
- fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK);
- if (fd < 0) {
- ksft_print_msg("Failed to open /proc/sys/vm/nr_hugepages: %s\n",
- strerror(errno));
- ret = -1;
- goto out;
- }
-
/*
* Request huge pages for about half of the free memory. The Kernel
* will allocate as much as it can, and we expect it will get at least 1/3
*/
- nr_hugepages_ul = mem_free / hugepage_size / 2;
- snprintf(target_nr_hugepages, sizeof(target_nr_hugepages),
- "%lu", nr_hugepages_ul);
-
- slen = strlen(target_nr_hugepages);
- if (write(fd, target_nr_hugepages, slen) != slen) {
- ksft_print_msg("Failed to write %lu to /proc/sys/vm/nr_hugepages: %s\n",
- nr_hugepages_ul, strerror(errno));
- goto close_fd;
- }
-
- lseek(fd, 0, SEEK_SET);
-
- if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) {
- ksft_print_msg("Failed to re-read from /proc/sys/vm/nr_hugepages: %s\n",
- strerror(errno));
- goto close_fd;
- }
+ nr_hugepages = mem_free / hugepage_size / 2;
+ hugetlb_set_nr_default_pages(nr_hugepages);
/* We should have been able to request at least 1/3 rd of the memory in
huge pages */
- nr_hugepages_ul = strtoul(nr_hugepages, NULL, 10);
- if (!nr_hugepages_ul) {
+ nr_hugepages = hugetlb_nr_default_pages();
+ if (!nr_hugepages) {
ksft_print_msg("ERROR: No memory is available as huge pages\n");
goto close_fd;
}
- compaction_index = mem_free/(nr_hugepages_ul * hugepage_size);
-
- lseek(fd, 0, SEEK_SET);
-
- if (write(fd, init_nr_hugepages, strlen(init_nr_hugepages))
- != strlen(init_nr_hugepages)) {
- ksft_print_msg("Failed to write value to /proc/sys/vm/nr_hugepages: %s\n",
- strerror(errno));
- goto close_fd;
- }
+ compaction_index = mem_free/(nr_hugepages * hugepage_size);
- ksft_print_msg("Number of huge pages allocated = %lu\n",
- nr_hugepages_ul);
+ ksft_print_msg("Number of huge pages allocated = %lu\n", nr_hugepages);
if (compaction_index > 3) {
ksft_print_msg("ERROR: Less than 1/%d of memory is available\n"
@@ -161,48 +120,10 @@ int check_compaction(unsigned long mem_free, unsigned long hugepage_size,
ret = 0;
close_fd:
- close(fd);
- out:
ksft_test_result(ret == 0, "check_compaction\n");
return ret;
}
-int set_zero_hugepages(unsigned long *initial_nr_hugepages)
-{
- int fd, ret = -1;
- char nr_hugepages[20] = {0};
-
- fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK);
- if (fd < 0) {
- ksft_print_msg("Failed to open /proc/sys/vm/nr_hugepages: %s\n",
- strerror(errno));
- goto out;
- }
- if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) {
- ksft_print_msg("Failed to read from /proc/sys/vm/nr_hugepages: %s\n",
- strerror(errno));
- goto close_fd;
- }
-
- lseek(fd, 0, SEEK_SET);
-
- /* Start with the initial condition of 0 huge pages */
- if (write(fd, "0", sizeof(char)) != sizeof(char)) {
- ksft_print_msg("Failed to write 0 to /proc/sys/vm/nr_hugepages: %s\n",
- strerror(errno));
- goto close_fd;
- }
-
- *initial_nr_hugepages = strtoul(nr_hugepages, NULL, 10);
- ret = 0;
-
- close_fd:
- close(fd);
-
- out:
- return ret;
-}
-
int main(int argc, char **argv)
{
struct rlimit lim;
@@ -212,18 +133,19 @@ int main(int argc, char **argv)
unsigned long mem_free = 0;
unsigned long hugepage_size = 0;
long mem_fragmentable_MB = 0;
- unsigned long initial_nr_hugepages;
ksft_print_header();
if (prereq() || geteuid())
ksft_exit_skip("Prerequisites unsatisfied\n");
- ksft_set_plan(1);
-
/* Start the test without hugepages reducing mem_free */
- if (set_zero_hugepages(&initial_nr_hugepages))
- ksft_exit_fail();
+ hugetlb_save_settings();
+ hugetlb_set_nr_default_pages(0);
+ if (hugetlb_nr_default_pages())
+ ksft_exit_skip("Could not reset nr_hugepages\n");
+
+ ksft_set_plan(1);
lim.rlim_cur = RLIM_INFINITY;
lim.rlim_max = RLIM_INFINITY;
@@ -268,8 +190,7 @@ int main(int argc, char **argv)
entry = entry->next;
}
- if (check_compaction(mem_free, hugepage_size,
- initial_nr_hugepages) == 0)
+ if (check_compaction(mem_free, hugepage_size) == 0)
ksft_exit_pass();
ksft_exit_fail();
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 30/53] selftests/mm: cow: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (28 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 29/53] selftests/mm: compaction_test: use HugeTLB helpers Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 31/53] selftests/mm: gup_longterm: " Mike Rapoport
` (22 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
cow tests skips HugeTLB tests if there are no free huge pages prepared
by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/cow.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
index 4321f4208fe3..1df513bf362d 100644
--- a/tools/testing/selftests/mm/cow.c
+++ b/tools/testing/selftests/mm/cow.c
@@ -1881,21 +1881,21 @@ int main(int argc, char **argv)
ksft_print_header();
+ hugepage_save_settings(true, true);
+
pagesize = getpagesize();
pmdsize = read_pmd_pagesize();
if (pmdsize) {
/* Only if THP is supported. */
thp_read_settings(&default_settings);
default_settings.hugepages[sz2ord(pmdsize, pagesize)].enabled = THP_INHERIT;
- thp_save_settings();
thp_push_settings(&default_settings);
ksft_print_msg("[INFO] detected PMD size: %zu KiB\n",
pmdsize / 1024);
nr_thpsizes = detect_thp_sizes(thpsizes, ARRAY_SIZE(thpsizes));
}
- nr_hugetlbsizes = detect_hugetlb_page_sizes(hugetlbsizes,
- ARRAY_SIZE(hugetlbsizes));
+ nr_hugetlbsizes = hugetlb_setup(2, hugetlbsizes, ARRAY_SIZE(hugetlbsizes));
has_huge_zeropage = detect_huge_zeropage();
ksft_set_plan(ARRAY_SIZE(anon_test_cases) * tests_per_anon_test_case() +
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 31/53] selftests/mm: gup_longterm: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (29 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 30/53] selftests/mm: cow: add setup of HugeTLB pages Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 32/53] selftests/mm: gup_test: " Mike Rapoport
` (21 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
gup_longterm tests skips HugeTLB tests if there are no free huge pages
prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/gup_longterm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/mm/gup_longterm.c b/tools/testing/selftests/mm/gup_longterm.c
index ab4eaf4feb7c..6e1de12bf28c 100644
--- a/tools/testing/selftests/mm/gup_longterm.c
+++ b/tools/testing/selftests/mm/gup_longterm.c
@@ -510,7 +510,7 @@ int main(int argc, char **argv)
int i;
pagesize = getpagesize();
- nr_hugetlbsizes = detect_hugetlb_page_sizes(hugetlbsizes,
+ nr_hugetlbsizes = hugetlb_setup(2, hugetlbsizes,
ARRAY_SIZE(hugetlbsizes));
ksft_print_header();
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 32/53] selftests/mm: gup_test: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (30 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 31/53] selftests/mm: gup_longterm: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 33/53] selftests/mm: hmm-tests: " Mike Rapoport
` (20 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
gup_test fails to run HugeTLB tests if there are no free huge pages
prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the
original settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/gup_test.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/tools/testing/selftests/mm/gup_test.c b/tools/testing/selftests/mm/gup_test.c
index fb8f9ae49efa..ddd239a69881 100644
--- a/tools/testing/selftests/mm/gup_test.c
+++ b/tools/testing/selftests/mm/gup_test.c
@@ -14,6 +14,7 @@
#include <mm/gup_test.h>
#include "kselftest.h"
#include "vm_util.h"
+#include "hugepage_settings.h"
#define MB (1UL << 20)
@@ -94,6 +95,7 @@ int main(int argc, char **argv)
int filed, i, opt, nr_pages = 1, thp = -1, write = 1, nthreads = 1, ret;
int flags = MAP_PRIVATE;
char *file = "/dev/zero";
+ bool hugetlb = false;
pthread_t *tid;
char *p;
@@ -168,6 +170,7 @@ int main(int argc, char **argv)
break;
case 'H':
flags |= (MAP_HUGETLB | MAP_ANONYMOUS);
+ hugetlb = true;
break;
default:
ksft_exit_fail_msg("Wrong argument\n");
@@ -199,6 +202,15 @@ int main(int argc, char **argv)
}
ksft_print_header();
+
+ if (hugetlb) {
+ unsigned long hp_size = default_huge_page_size();
+
+ size = (size + hp_size - 1) & ~(hp_size - 1);
+ if (!hugetlb_setup_default(size / hp_size))
+ ksft_exit_skip("Not enough huge pages\n");
+ }
+
ksft_set_plan(nthreads);
filed = open(file, O_RDWR|O_CREAT, 0664);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 33/53] selftests/mm: hmm-tests: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (31 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 32/53] selftests/mm: gup_test: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 34/53] selftests/mm: hugepage_dio: " Mike Rapoport
` (19 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hmm-tests skips HugeTLB tests if there are no free huge pages prepared by a
wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Since kselftest_harness runs fixture setup and the tests in child
processes, use HUGETLB_SETUP_DEFAULT_PAGES() that defines a constructor
that runs in the main process and add verification that there are enough
free huge pages to the tests that use them.
Replace exit() calls with _exit() to avoid restoring HugeTLB settings in
the middle of test and use SIGLILL to kill a child process in
hmm_cow_in_device test to avoid interference with signal handlers in
hugepage_restore_settings().
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hmm-tests.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/mm/hmm-tests.c b/tools/testing/selftests/mm/hmm-tests.c
index 409b11cad4bc..70c7ae989c01 100644
--- a/tools/testing/selftests/mm/hmm-tests.c
+++ b/tools/testing/selftests/mm/hmm-tests.c
@@ -69,6 +69,9 @@ enum {
#ifndef FOLL_LONGTERM
#define FOLL_LONGTERM 0x100 /* mapping lifetime is indefinite */
#endif
+
+HUGETLB_SETUP_DEFAULT_PAGES(1)
+
FIXTURE(hmm)
{
int fd;
@@ -632,7 +635,7 @@ TEST_F(hmm, anon_write_child)
}
close(child_fd);
- exit(0);
+ _exit(0);
}
}
}
@@ -712,7 +715,7 @@ TEST_F(hmm, anon_write_child_shared)
ASSERT_EQ(ptr[i], -i);
close(child_fd);
- exit(0);
+ _exit(0);
}
/*
@@ -784,8 +787,9 @@ TEST_F(hmm, anon_write_hugetlbfs)
int *ptr;
int ret;
- if (!default_hsize)
- SKIP(return, "Huge page size could not be determined");
+ if (!hugetlb_free_default_pages())
+ SKIP(return, "Not enough huge pages");
+ default_hsize = default_huge_page_size();
size = ALIGN(TWOMEG, default_hsize);
npages = size >> self->page_shift;
@@ -1564,9 +1568,9 @@ TEST_F(hmm, compound)
unsigned long i;
/* Skip test if we can't allocate a hugetlbfs page. */
-
- if (!default_hsize)
- SKIP(return, "Huge page size could not be determined");
+ if (!hugetlb_free_default_pages())
+ SKIP(return, "Not enough huge pages");
+ default_hsize = default_huge_page_size();
size = ALIGN(TWOMEG, default_hsize);
npages = size >> self->page_shift;
@@ -2025,10 +2029,10 @@ TEST_F(hmm, hmm_cow_in_device)
ptr[i] = i;
/* Terminate child and wait */
- EXPECT_EQ(0, kill(pid, SIGTERM));
+ EXPECT_EQ(0, kill(pid, SIGKILL));
EXPECT_EQ(pid, waitpid(pid, &status, 0));
EXPECT_NE(0, WIFSIGNALED(status));
- EXPECT_EQ(SIGTERM, WTERMSIG(status));
+ EXPECT_EQ(SIGKILL, WTERMSIG(status));
/* Take snapshot to CPU pagetables */
ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 34/53] selftests/mm: hugepage_dio: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (32 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 33/53] selftests/mm: hmm-tests: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 35/53] selftests/mm: hugetlb_fault_after_madv: " Mike Rapoport
` (18 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugepage_dio test fails if there are no free huge pages prepared by a
wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb_dio.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb_dio.c b/tools/testing/selftests/mm/hugetlb_dio.c
index 47019433ddaf..fb4600570e13 100644
--- a/tools/testing/selftests/mm/hugetlb_dio.c
+++ b/tools/testing/selftests/mm/hugetlb_dio.c
@@ -85,8 +85,6 @@ static void run_dio_using_hugetlb(int fd, unsigned int start_off,
/* Get the default huge page size */
h_pagesize = default_huge_page_size();
- if (!h_pagesize)
- ksft_exit_fail_msg("Unable to determine huge page size\n");
/* Reset file position since fd is shared across tests */
if (lseek(fd, 0, SEEK_SET) < 0)
@@ -94,10 +92,6 @@ static void run_dio_using_hugetlb(int fd, unsigned int start_off,
/* Get the free huge pages before allocation */
free_hpage_b = hugetlb_free_default_pages();
- if (free_hpage_b == 0) {
- close(fd);
- ksft_exit_skip("No free hugepage, exiting!\n");
- }
/* Allocate a hugetlb page */
orig_buffer = mmap(NULL, h_pagesize, mmap_prot, mmap_flags, -1, 0);
@@ -141,8 +135,8 @@ int main(void)
ksft_print_header();
- /* Check if huge pages are free */
- if (!hugetlb_free_default_pages())
+ /* request a huge page */
+ if (!hugetlb_setup_default(1))
ksft_exit_skip("No free hugepage, exiting\n");
fd = open("/tmp", O_TMPFILE | O_RDWR | O_DIRECT, 0664);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 35/53] selftests/mm: hugetlb_fault_after_madv: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (33 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 34/53] selftests/mm: hugepage_dio: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 36/53] selftests/mm: hugetlb-madvise: " Mike Rapoport
` (17 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugetlb_fault_after_madv test skips testing if there are no free huge
pages prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb_fault_after_madv.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb_fault_after_madv.c b/tools/testing/selftests/mm/hugetlb_fault_after_madv.c
index c718dd065d53..481863cc5fda 100644
--- a/tools/testing/selftests/mm/hugetlb_fault_after_madv.c
+++ b/tools/testing/selftests/mm/hugetlb_fault_after_madv.c
@@ -54,7 +54,6 @@ void *madv(void *unused)
int main(void)
{
- unsigned long free_hugepages;
pthread_t thread1, thread2;
/*
* On kernel 6.4, we are able to reproduce the problem with ~1000
@@ -78,10 +77,9 @@ int main(void)
ksft_print_msg("[INFO] detected default hugetlb page size: %zu KiB\n",
huge_page_size / 1024);
- free_hugepages = hugetlb_free_default_pages();
- if (free_hugepages != 1) {
+ if (!hugetlb_setup_default(1)) {
ksft_exit_skip("This test needs one and only one page to execute. Got %lu\n",
- free_hugepages);
+ hugetlb_free_default_pages());
}
while (max--) {
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 36/53] selftests/mm: hugetlb-madvise: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (34 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 35/53] selftests/mm: hugetlb_fault_after_madv: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 37/53] selftests/mm: hugetlb_madv_vs_map: " Mike Rapoport
` (16 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugetlb-madvise test skips testing if there are no free huge pages
prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb-madvise.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c
index 3c08eb6db6a2..b20648d025e6 100644
--- a/tools/testing/selftests/mm/hugetlb-madvise.c
+++ b/tools/testing/selftests/mm/hugetlb-madvise.c
@@ -68,9 +68,9 @@ int main(int argc, char **argv)
if (!base_page_size)
ksft_exit_fail_msg("Unable to determine base page size\n");
+ if (!hugetlb_setup_default(MIN_FREE_PAGES))
+ ksft_exit_skip("Not enough free huge pages (have %lu, need %d)\n", hugetlb_free_default_pages(), MIN_FREE_PAGES);
free_hugepages = hugetlb_free_default_pages();
- if (free_hugepages < MIN_FREE_PAGES)
- ksft_exit_skip("Not enough free huge pages (have %lu, need %d)\n", free_hugepages, MIN_FREE_PAGES);
fd = memfd_create(argv[0], MFD_HUGETLB);
if (fd < 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 37/53] selftests/mm: hugetlb_madv_vs_map: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (35 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 36/53] selftests/mm: hugetlb-madvise: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 38/53] selftests/mm: hugetlb-mmap: " Mike Rapoport
` (15 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugetlb_madv_vs_map test skips testing if there are no free huge pages
prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb_madv_vs_map.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
index dfbd71a7f709..6c95dd23ca81 100644
--- a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
+++ b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c
@@ -77,7 +77,6 @@ void *map_extra(void *unused)
int main(void)
{
pthread_t thread1, thread2, thread3;
- unsigned long free_hugepages;
void *ret;
/*
@@ -89,11 +88,9 @@ int main(void)
ksft_print_header();
ksft_set_plan(1);
- free_hugepages = hugetlb_free_default_pages();
-
- if (free_hugepages != 1)
+ if (!hugetlb_setup_default(1))
ksft_exit_skip("This test needs one and only one page to execute. Got %lu\n",
- free_hugepages);
+ hugetlb_free_default_pages());
mmap_size = default_huge_page_size();
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 38/53] selftests/mm: hugetlb-mmap: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (36 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 37/53] selftests/mm: hugetlb_madv_vs_map: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 39/53] selftests/mm: hugetlb-mremap: " Mike Rapoport
` (14 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugetlb-mmap test fails if there are no free huge pages prepared by a
wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb-mmap.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb-mmap.c b/tools/testing/selftests/mm/hugetlb-mmap.c
index 5be68fbc36dc..d4edb233101d 100644
--- a/tools/testing/selftests/mm/hugetlb-mmap.c
+++ b/tools/testing/selftests/mm/hugetlb-mmap.c
@@ -107,10 +107,9 @@ int main(int argc, char **argv)
{
size_t hugepage_size;
size_t length = LENGTH;
- int shift = 0;
+ int shift = 0, nr;
ksft_print_header();
- ksft_set_plan(2);
if (argc > 1)
length = atol(argv[1]) << 20;
@@ -126,9 +125,13 @@ int main(int argc, char **argv)
}
/* munmap with fail if the length is not page aligned */
- if (hugepage_size > length)
- length = hugepage_size;
+ length = (length + hugepage_size) & ~(hugepage_size - 1);
+ nr = length / hugepage_size;
+
+ if (!hugetlb_setup_default(nr))
+ ksft_exit_skip("Not enough %lu Kb pages\n", hugepage_size >> 10);
+ ksft_set_plan(2);
ksft_print_msg("Mapping %lu Mbytes\n", (unsigned long)length >> 20);
test_anon_mmap(length, shift);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 39/53] selftests/mm: hugetlb-mremap: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (37 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 38/53] selftests/mm: hugetlb-mmap: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 40/53] selftests/mm: hugetlb-shm: " Mike Rapoport
` (13 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugetlb-mremap test fails if there are no free huge pages prepared by a
wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb-mremap.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/mm/hugetlb-mremap.c b/tools/testing/selftests/mm/hugetlb-mremap.c
index 1c87c39780c5..09241a279ec2 100644
--- a/tools/testing/selftests/mm/hugetlb-mremap.c
+++ b/tools/testing/selftests/mm/hugetlb-mremap.c
@@ -26,6 +26,7 @@
#include <stdbool.h>
#include "kselftest.h"
#include "vm_util.h"
+#include "hugepage_settings.h"
#define DEFAULT_LENGTH_MB 10UL
#define MB_TO_BYTES(x) (x * 1024 * 1024)
@@ -108,8 +109,9 @@ static void register_region_with_uffd(char *addr, size_t len)
int main(int argc, char *argv[])
{
+ unsigned long hugepage_size;
+ int ret = 0, fd, nr;
size_t length = 0;
- int ret = 0, fd;
ksft_print_header();
ksft_set_plan(1);
@@ -125,7 +127,14 @@ int main(int argc, char *argv[])
else
length = DEFAULT_LENGTH_MB;
+ hugepage_size = default_huge_page_size();
length = MB_TO_BYTES(length);
+ length = (length + hugepage_size) & ~(hugepage_size - 1);
+ nr = length / hugepage_size;
+
+ if (!hugetlb_setup_default(nr))
+ ksft_exit_skip("Not enough huge pages\n");
+
fd = memfd_create(argv[0], MFD_HUGETLB);
if (fd < 0)
ksft_exit_fail_msg("Open failed: %s\n", strerror(errno));
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 40/53] selftests/mm: hugetlb-shm: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (38 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 39/53] selftests/mm: hugetlb-mremap: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 41/53] selftests/mm: hugetlb-soft-online: " Mike Rapoport
` (12 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugetlb-shm test fails if there are no free huge pages prepared by a
wrapper script and shm liimts in proc are too low.
Add setup of HugeTLB pages and shm limits to the test and make sure that
the original settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb-shm.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/tools/testing/selftests/mm/hugetlb-shm.c b/tools/testing/selftests/mm/hugetlb-shm.c
index 10e4baa091f2..e721ef17974c 100644
--- a/tools/testing/selftests/mm/hugetlb-shm.c
+++ b/tools/testing/selftests/mm/hugetlb-shm.c
@@ -29,9 +29,24 @@
#include <sys/mman.h>
#include "vm_util.h"
+#include "hugepage_settings.h"
#define LENGTH (256UL*1024*1024)
+static void prepare(void)
+{
+ unsigned long length, hugepage_size, nr;
+
+ hugepage_size = default_huge_page_size();
+ length = (LENGTH + hugepage_size) & ~(hugepage_size - 1);
+ nr = length / hugepage_size;
+
+ if (!hugetlb_setup_default(nr))
+ ksft_exit_skip("Not enough free huge pages\n");
+
+ shm_limits_prepare(length);
+}
+
int main(void)
{
int shmid;
@@ -41,6 +56,8 @@ int main(void)
ksft_print_header();
ksft_set_plan(1);
+ prepare();
+
shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
if (shmid < 0)
ksft_exit_fail_perror("shmget");
@@ -79,3 +96,5 @@ int main(void)
ksft_test_result_pass("hugepage using SysV shmget/shmat\n");
ksft_finished();
}
+
+SHM_LIMITS_RESTORE()
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 41/53] selftests/mm: hugetlb-soft-online: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (39 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 40/53] selftests/mm: hugetlb-shm: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 42/53] selftests/mm: hugetlb-vmemmap: " Mike Rapoport
` (11 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugetlb-soft-online test uses open coded access to /proc to determine
availability of huge pages and fails if there are no enough free huget
pages..
Replace open coded access to /proc with hugepage helpers and add setup
of HugeTLB pages to the test and make sure that the original settings
are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
.../selftests/mm/hugetlb-soft-offline.c | 45 ++++---------------
1 file changed, 8 insertions(+), 37 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb-soft-offline.c b/tools/testing/selftests/mm/hugetlb-soft-offline.c
index a8bc02688085..bc202e4ed2bd 100644
--- a/tools/testing/selftests/mm/hugetlb-soft-offline.c
+++ b/tools/testing/selftests/mm/hugetlb-soft-offline.c
@@ -6,9 +6,7 @@
* - if enable_soft_offline = 1, a hugepage should be dissolved and
* nr_hugepages/free_hugepages should be reduced by 1.
*
- * Before running, make sure more than 2 hugepages of default_hugepagesz
- * are allocated. For example, if /proc/meminfo/Hugepagesize is 2048kB:
- * echo 8 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
+ * The test allocates 8 default hugepages
*/
#define _GNU_SOURCE
@@ -25,6 +23,7 @@
#include <sys/types.h>
#include "kselftest.h"
+#include "hugepage_settings.h"
#ifndef MADV_SOFT_OFFLINE
#define MADV_SOFT_OFFLINE 101
@@ -100,32 +99,6 @@ static int set_enable_soft_offline(int value)
return 0;
}
-static int read_nr_hugepages(unsigned long hugepage_size,
- unsigned long *nr_hugepages)
-{
- char buffer[256] = {0};
- char cmd[256] = {0};
-
- sprintf(cmd, "cat /sys/kernel/mm/hugepages/hugepages-%ldkB/nr_hugepages",
- hugepage_size);
- FILE *cmdfile = popen(cmd, "r");
-
- if (cmdfile == NULL) {
- ksft_perror(EPREFIX "failed to popen nr_hugepages");
- return -1;
- }
-
- if (!fgets(buffer, sizeof(buffer), cmdfile)) {
- ksft_perror(EPREFIX "failed to read nr_hugepages");
- pclose(cmdfile);
- return -1;
- }
-
- *nr_hugepages = atoll(buffer);
- pclose(cmdfile);
- return 0;
-}
-
static int create_hugetlbfs_file(struct statfs *file_stat)
{
int fd;
@@ -177,20 +150,14 @@ static void test_soft_offline_common(int enable_soft_offline)
ksft_exit_fail_msg("Failed to set enable_soft_offline\n");
}
- if (read_nr_hugepages(hugepagesize_kb, &nr_hugepages_before) != 0) {
- close(fd);
- ksft_exit_fail_msg("Failed to read nr_hugepages\n");
- }
+ nr_hugepages_before = hugetlb_nr_default_pages();
ksft_print_msg("Before MADV_SOFT_OFFLINE nr_hugepages=%ld\n",
nr_hugepages_before);
ret = do_soft_offline(fd, 2 * file_stat.f_bsize, expect_errno);
- if (read_nr_hugepages(hugepagesize_kb, &nr_hugepages_after) != 0) {
- close(fd);
- ksft_exit_fail_msg("Failed to read nr_hugepages\n");
- }
+ nr_hugepages_after = hugetlb_nr_default_pages();
ksft_print_msg("After MADV_SOFT_OFFLINE nr_hugepages=%ld\n",
nr_hugepages_after);
@@ -219,6 +186,10 @@ static void test_soft_offline_common(int enable_soft_offline)
int main(int argc, char **argv)
{
ksft_print_header();
+
+ if (!hugetlb_setup_default(8))
+ ksft_exit_skip("not enough hugetlb pages\n");
+
ksft_set_plan(2);
test_soft_offline_common(1);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 42/53] selftests/mm: hugetlb-vmemmap: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (40 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 41/53] selftests/mm: hugetlb-soft-online: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 43/53] selftests/mm: migration: " Mike Rapoport
` (10 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
hugetlb-vmemmap test fails if there are no free huge pages prepared by a
wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/hugetlb-vmemmap.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/testing/selftests/mm/hugetlb-vmemmap.c b/tools/testing/selftests/mm/hugetlb-vmemmap.c
index af5786bebfd1..507df78a158d 100644
--- a/tools/testing/selftests/mm/hugetlb-vmemmap.c
+++ b/tools/testing/selftests/mm/hugetlb-vmemmap.c
@@ -97,6 +97,9 @@ int main(int argc, char **argv)
ksft_print_header();
ksft_set_plan(1);
+ if (!hugetlb_setup_default(1))
+ ksft_exit_skip("Not enough free huge pages\n");
+
pagesize = psize();
maplength = default_huge_page_size();
if (!maplength)
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 43/53] selftests/mm: migration: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (41 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 42/53] selftests/mm: hugetlb-vmemmap: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 44/53] selftests/mm: pagemap_ioctl: " Mike Rapoport
` (9 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
migration skips HugeTLB tests if there are no free huge pages
prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Since kselftest_harness runs fixture setup and the tests in child
processes, use HUGETLB_SETUP_DEFAULT_PAGES() that defines a constructor
that runs in the main process and add verification that there are enough
free huge pages to the tests that use them.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/migration.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tools/testing/selftests/mm/migration.c b/tools/testing/selftests/mm/migration.c
index ccf42002ce86..61fb00953f83 100644
--- a/tools/testing/selftests/mm/migration.c
+++ b/tools/testing/selftests/mm/migration.c
@@ -23,6 +23,8 @@
#define MAX_RETRIES 100
#define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1)))
+HUGETLB_SETUP_DEFAULT_PAGES(1)
+
FIXTURE(migration)
{
pthread_t *threads;
@@ -277,6 +279,9 @@ TEST_F_TIMEOUT(migration, private_anon_htlb, 2*RUNTIME)
if (!hugepage_size)
SKIP(return, "Reading HugeTLB pagesize failed\n");
+ if (hugetlb_free_default_pages() < 1)
+ SKIP(return, "Not enough huge pages\n");
+
ptr = mmap(NULL, hugepage_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
ASSERT_NE(ptr, MAP_FAILED);
@@ -308,6 +313,9 @@ TEST_F_TIMEOUT(migration, shared_anon_htlb, 2*RUNTIME)
if (!hugepage_size)
SKIP(return, "Reading HugeTLB pagesize failed\n");
+ if (hugetlb_free_default_pages() < 1)
+ SKIP(return, "Not enough huge pages\n");
+
ptr = mmap(NULL, hugepage_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
ASSERT_NE(ptr, MAP_FAILED);
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 44/53] selftests/mm: pagemap_ioctl: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (42 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 43/53] selftests/mm: migration: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 45/53] selftests/mm: protection_keys: use library code for HugeTLB setup Mike Rapoport
` (8 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
pagemap-ioctl skips HugeTLB tests if there are no free huge pages
prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/pagemap_ioctl.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/mm/pagemap_ioctl.c b/tools/testing/selftests/mm/pagemap_ioctl.c
index 7f9428d6062c..e2c62cb6978f 100644
--- a/tools/testing/selftests/mm/pagemap_ioctl.c
+++ b/tools/testing/selftests/mm/pagemap_ioctl.c
@@ -7,8 +7,6 @@
#include <sys/mman.h>
#include <errno.h>
#include <malloc.h>
-#include "vm_util.h"
-#include "kselftest.h"
#include <linux/types.h>
#include <linux/memfd.h>
#include <linux/userfaultfd.h>
@@ -23,6 +21,10 @@
#include <sys/ipc.h>
#include <sys/shm.h>
+#include "vm_util.h"
+#include "kselftest.h"
+#include "hugepage_settings.h"
+
#define PAGEMAP_BITS_ALL (PAGE_IS_WPALLOWED | PAGE_IS_WRITTEN | \
PAGE_IS_FILE | PAGE_IS_PRESENT | \
PAGE_IS_SWAPPED | PAGE_IS_PFNZERO | \
@@ -1554,6 +1556,9 @@ int main(int __attribute__((unused)) argc, char *argv[])
if (init_uffd())
ksft_exit_skip("Failed to initialize userfaultfd\n");
+ if (!hugetlb_setup_default(4))
+ ksft_exit_skip("Not enough huge pages\n");
+
ksft_set_plan(117);
page_size = getpagesize();
@@ -1605,7 +1610,7 @@ int main(int __attribute__((unused)) argc, char *argv[])
}
/* 5. SHM Hugetlb page testing */
- mem_size = 2*1024*1024;
+ mem_size = default_huge_page_size();
mem = gethugetlb_mem(mem_size, &shmid);
if (mem) {
wp_init(mem, mem_size);
@@ -1633,7 +1638,7 @@ int main(int __attribute__((unused)) argc, char *argv[])
}
/* 7. File Hugetlb testing */
- mem_size = 2*1024*1024;
+ mem_size = default_huge_page_size();
fd = memfd_create("uffd-test", MFD_HUGETLB | MFD_NOEXEC_SEAL);
if (fd < 0)
ksft_exit_fail_msg("uffd-test creation failed %d %s\n", errno, strerror(errno));
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 45/53] selftests/mm: protection_keys: use library code for HugeTLB setup
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (43 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 44/53] selftests/mm: pagemap_ioctl: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 46/53] selftests/mm: thuge-gen: add setup of HugeTLB pages Mike Rapoport
` (7 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
protection_keys open codes setup of HugeTLB pages.
Replace it with the library functions from hugepage_setup.
Replace exit() calls with _exit() to avoid restoring HugeTLB settings in
the middle of test.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/protection_keys.c | 51 ++++++--------------
1 file changed, 15 insertions(+), 36 deletions(-)
diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c
index c069250969f5..6657f13bc7e7 100644
--- a/tools/testing/selftests/mm/protection_keys.c
+++ b/tools/testing/selftests/mm/protection_keys.c
@@ -47,6 +47,7 @@
#include <setjmp.h>
#include "pkey-helpers.h"
+#include "hugepage_settings.h"
int iteration_nr = 1;
int test_nr;
@@ -61,6 +62,7 @@ noinline int read_ptr(int *ptr)
return *ptr;
}
+#if CONTROL_TRACING > 0
static void cat_into_file(char *str, char *file)
{
int fd = open(file, O_RDWR);
@@ -86,7 +88,6 @@ static void cat_into_file(char *str, char *file)
close(fd);
}
-#if CONTROL_TRACING > 0
static int warned_tracing;
static int tracing_root_ok(void)
{
@@ -709,50 +710,28 @@ static void *malloc_pkey_anon_huge(long size, int prot, u16 pkey)
}
static int hugetlb_setup_ok;
-#define SYSFS_FMT_NR_HUGE_PAGES "/sys/kernel/mm/hugepages/hugepages-%ldkB/nr_hugepages"
#define GET_NR_HUGE_PAGES 10
static void setup_hugetlbfs(void)
{
- int err;
- int fd;
- char buf[256];
- long hpagesz_kb;
- long hpagesz_mb;
+ long hpagesz_mb = HPAGE_SIZE / 1024 / 1024;
+ unsigned long free_pages;
if (geteuid() != 0) {
ksft_print_msg("WARNING: not run as root, can not do hugetlb test\n");
return;
}
- cat_into_file(__stringify(GET_NR_HUGE_PAGES), "/proc/sys/vm/nr_hugepages");
-
/*
- * Now go make sure that we got the pages and that they
+ * Make sure that we got the pages and that they
* are PMD-level pages. Someone might have made PUD-level
* pages the default.
*/
- hpagesz_kb = HPAGE_SIZE / 1024;
- hpagesz_mb = hpagesz_kb / 1024;
- sprintf(buf, SYSFS_FMT_NR_HUGE_PAGES, hpagesz_kb);
- fd = open(buf, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "opening sysfs %ldM hugetlb config: %s\n",
- hpagesz_mb, strerror(errno));
- return;
- }
-
- /* -1 to guarantee leaving the trailing \0 */
- err = read(fd, buf, sizeof(buf)-1);
- close(fd);
- if (err <= 0) {
- fprintf(stderr, "reading sysfs %ldM hugetlb config: %s\n",
- hpagesz_mb, strerror(errno));
- return;
- }
-
- if (atoi(buf) != GET_NR_HUGE_PAGES) {
- fprintf(stderr, "could not confirm %ldM pages, got: '%s' expected %d\n",
- hpagesz_mb, buf, GET_NR_HUGE_PAGES);
+ hugetlb_save_settings();
+ hugetlb_set_nr_pages(HPAGE_SIZE, GET_NR_HUGE_PAGES);
+ free_pages = hugetlb_free_pages(HPAGE_SIZE);
+ if (free_pages < GET_NR_HUGE_PAGES) {
+ ksft_print_msg("could not confirm %ldM pages, got: '%ld' expected %d\n",
+ hpagesz_mb, free_pages, GET_NR_HUGE_PAGES);
return;
}
@@ -1129,7 +1108,7 @@ static void become_child(void)
/* in the child */
return;
}
- exit(0);
+ _exit(0);
}
/* Assumes that all pkeys other than 'pkey' are unallocated */
@@ -1508,18 +1487,18 @@ static void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
* checking
*/
if (__read_pkey_reg() != new_pkru)
- exit(1);
+ _exit(1);
/* Stop and allow the tracer to clear XSTATE_BV for PKRU */
raise(SIGSTOP);
if (__read_pkey_reg() != 0)
- exit(1);
+ _exit(1);
/* Stop and allow the tracer to examine PKRU */
raise(SIGSTOP);
- exit(0);
+ _exit(0);
}
pkey_assert(child == waitpid(child, &status, 0));
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 46/53] selftests/mm: thuge-gen: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (44 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 45/53] selftests/mm: protection_keys: use library code for HugeTLB setup Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 47/53] selftests/mm: uffd-stress: use hugetlb_save and alloc huge pages Mike Rapoport
` (6 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
thuge-gen skips tests if there are no free huge pages prepared by a wrapper
script and shm liimts in proc are too low.
Replace custom detection of huge pages with the library functions and add
setup of HugeTLB pages and shm limits to the test and make sure that the
original settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/thuge-gen.c | 79 ++++----------------------
1 file changed, 11 insertions(+), 68 deletions(-)
diff --git a/tools/testing/selftests/mm/thuge-gen.c b/tools/testing/selftests/mm/thuge-gen.c
index 1007bc8aa57c..b63d87d72a7d 100644
--- a/tools/testing/selftests/mm/thuge-gen.c
+++ b/tools/testing/selftests/mm/thuge-gen.c
@@ -38,15 +38,6 @@
#ifndef SHM_HUGE_SHIFT
#define SHM_HUGE_SHIFT 26
#endif
-#ifndef SHM_HUGE_MASK
-#define SHM_HUGE_MASK 0x3f
-#endif
-#ifndef SHM_HUGE_2MB
-#define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT)
-#endif
-#ifndef SHM_HUGE_1GB
-#define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT)
-#endif
#define NUM_PAGESIZES 5
#define NUM_PAGES 4
@@ -64,32 +55,10 @@ int ilog2(unsigned long v)
void show(unsigned long ps)
{
- char buf[100];
-
if (ps == getpagesize())
return;
- ksft_print_msg("%luMB: ", ps >> 20);
-
- fflush(stdout);
- snprintf(buf, sizeof buf,
- "cat /sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages",
- ps >> 10);
- system(buf);
-}
-
-unsigned long read_free(unsigned long ps)
-{
- unsigned long val = 0;
- char buf[100];
-
- snprintf(buf, sizeof(buf),
- "/sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages",
- ps >> 10);
- if (read_sysfs(buf, &val) && ps != getpagesize())
- ksft_print_msg("missing %s\n", buf);
-
- return val;
+ ksft_print_msg("%luMB: %ld\n", ps >> 20, hugetlb_free_pages(ps));
}
void test_mmap(unsigned long size, unsigned flags)
@@ -97,14 +66,14 @@ void test_mmap(unsigned long size, unsigned flags)
char *map;
unsigned long before, after;
- before = read_free(size);
+ before = hugetlb_free_pages(size);
map = mmap(NULL, size*NUM_PAGES, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB|flags, -1, 0);
if (map == MAP_FAILED)
ksft_exit_fail_msg("mmap: %s\n", strerror(errno));
memset(map, 0xff, size*NUM_PAGES);
- after = read_free(size);
+ after = hugetlb_free_pages(size);
show(size);
ksft_test_result(size == getpagesize() || (before - after) == NUM_PAGES,
@@ -121,7 +90,7 @@ void test_shmget(unsigned long size, unsigned flags)
struct shm_info i;
char *map;
- before = read_free(size);
+ before = hugetlb_free_pages(size);
id = shmget(IPC_PRIVATE, size * NUM_PAGES, IPC_CREAT|0600|flags);
if (id < 0) {
if (errno == EPERM) {
@@ -142,7 +111,7 @@ void test_shmget(unsigned long size, unsigned flags)
shmctl(id, IPC_RMID, NULL);
memset(map, 0xff, size*NUM_PAGES);
- after = read_free(size);
+ after = hugetlb_free_pages(size);
show(size);
ksft_test_result(size == getpagesize() || (before - after) == NUM_PAGES,
@@ -154,43 +123,15 @@ void test_shmget(unsigned long size, unsigned flags)
void find_pagesizes(void)
{
unsigned long largest = getpagesize();
- unsigned long shmmax_val = 0;
int i;
- glob_t g;
- glob("/sys/kernel/mm/hugepages/hugepages-*kB", 0, NULL, &g);
- assert(g.gl_pathc <= NUM_PAGESIZES);
- for (i = 0; (i < g.gl_pathc) && (num_page_sizes < NUM_PAGESIZES); i++) {
- sscanf(g.gl_pathv[i], "/sys/kernel/mm/hugepages/hugepages-%lukB",
- &page_sizes[num_page_sizes]);
- page_sizes[num_page_sizes] <<= 10;
- ksft_print_msg("Found %luMB\n", page_sizes[i] >> 20);
+ num_page_sizes = hugetlb_setup(NUM_PAGES, page_sizes, ARRAY_SIZE(page_sizes));
- if (page_sizes[num_page_sizes] > largest)
+ for (i = 0; i < num_page_sizes; i++)
+ if (page_sizes[i] > largest)
largest = page_sizes[i];
- if (read_free(page_sizes[num_page_sizes]) >= NUM_PAGES)
- num_page_sizes++;
- else
- ksft_print_msg("SKIP for size %lu MB as not enough huge pages, need %u\n",
- page_sizes[num_page_sizes] >> 20, NUM_PAGES);
- }
- globfree(&g);
-
- read_sysfs("/proc/sys/kernel/shmmax", &shmmax_val);
- if (shmmax_val < NUM_PAGES * largest) {
- ksft_print_msg("WARNING: shmmax is too small to run this test.\n");
- ksft_print_msg("Please run the following command to increase shmmax:\n");
- ksft_print_msg("echo %lu > /proc/sys/kernel/shmmax\n", largest * NUM_PAGES);
- ksft_exit_skip("Test skipped due to insufficient shmmax value.\n");
- }
-
-#if defined(__x86_64__)
- if (largest != 1U<<30) {
- ksft_exit_skip("No GB pages available on x86-64\n"
- "Please boot with hugepagesz=1G hugepages=%d\n", NUM_PAGES);
- }
-#endif
+ shm_limits_prepare(NUM_PAGES * largest);
}
int main(void)
@@ -233,3 +174,5 @@ int main(void)
ksft_finished();
}
+
+SHM_LIMITS_RESTORE()
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 47/53] selftests/mm: uffd-stress: use hugetlb_save and alloc huge pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (45 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 46/53] selftests/mm: thuge-gen: add setup of HugeTLB pages Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 48/53] selftests/mm: uffd-unit-tests: add setup of HugeTLB pages Mike Rapoport
` (5 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
uffd-stress skips HugeTLB tests if there are no free huge pages prepared
by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/uffd-stress.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/mm/uffd-stress.c b/tools/testing/selftests/mm/uffd-stress.c
index 7e37cf3d27f6..9693d042f16f 100644
--- a/tools/testing/selftests/mm/uffd-stress.c
+++ b/tools/testing/selftests/mm/uffd-stress.c
@@ -479,9 +479,12 @@ int main(int argc, char **argv)
* Ensure nr_parallel - 1 hugepages on top of that to account
* for racy extra reservation of hugepages.
*/
- if (gopts->test_type == TEST_HUGETLB &&
- hugetlb_free_default_pages() < 2 * (bytes / gopts->page_size) + gopts->nr_parallel - 1)
- ksft_exit_skip("Skipping userfaultfd... not enough hugepages\n");
+ if (gopts->test_type == TEST_HUGETLB) {
+ unsigned long nr = 2 * (bytes / gopts->page_size) + gopts->nr_parallel - 1;
+
+ if (!hugetlb_setup_default(nr))
+ ksft_exit_skip("Skipping userfaultfd... not enough hugepages\n");
+ }
gopts->nr_pages_per_cpu = bytes / gopts->page_size / gopts->nr_parallel;
if (!gopts->nr_pages_per_cpu) {
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 48/53] selftests/mm: uffd-unit-tests: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (46 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 47/53] selftests/mm: uffd-stress: use hugetlb_save and alloc huge pages Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 49/53] selftests/mm: uffd-wp-mremap: " Mike Rapoport
` (4 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
uffd-unit-tests skips HugeTLB tests if there are no free huge pages
prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Replace exit() calls with _exit() to avoid restoring HugeTLB settings in
the middle of test.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/uffd-unit-tests.c | 31 +++++++++++++++++---
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/mm/uffd-unit-tests.c b/tools/testing/selftests/mm/uffd-unit-tests.c
index 1a33db281f8a..20e1829db91f 100644
--- a/tools/testing/selftests/mm/uffd-unit-tests.c
+++ b/tools/testing/selftests/mm/uffd-unit-tests.c
@@ -305,7 +305,7 @@ static int pagemap_test_fork(uffd_global_test_opts_t *gopts, bool with_event, bo
if (test_pin)
unpin_pages(&args);
/* Succeed */
- exit(0);
+ _exit(0);
}
waitpid(child, &result, 0);
@@ -773,7 +773,7 @@ static void uffd_sigbus_test_common(uffd_global_test_opts_t *gopts, bool wp)
err("fork");
if (!pid)
- exit(faulting_process(gopts, 2, wp));
+ _exit(faulting_process(gopts, 2, wp));
waitpid(pid, &err, 0);
if (err)
@@ -827,7 +827,7 @@ static void uffd_events_test_common(uffd_global_test_opts_t *gopts, bool wp)
err("fork");
if (!pid)
- exit(faulting_process(gopts, 0, wp));
+ _exit(faulting_process(gopts, 0, wp));
waitpid(pid, &err, 0);
if (err)
@@ -1706,11 +1706,32 @@ static int uffd_count_tests(int n_tests, int n_mems, const char *test_filter)
return count;
}
+static unsigned long uffd_setup_hugetlb(void)
+{
+ unsigned long nr_hugepages, hp_size;
+
+ hugetlb_save_settings();
+ hp_size = default_huge_page_size();
+
+ if (!hp_size)
+ return 0;
+
+ /* need twice UFFD_TEST_MEM_SIZE, one for src area and one for dst */
+ nr_hugepages = 2 * MAX(UFFD_TEST_MEM_SIZE, hp_size * 2) / hp_size;
+ hugetlb_set_nr_default_pages(nr_hugepages);
+
+ if (hugetlb_free_default_pages() < nr_hugepages)
+ return 0;
+
+ return hp_size;
+}
+
int main(int argc, char *argv[])
{
int n_tests = sizeof(uffd_tests) / sizeof(uffd_test_case_t);
int n_mems = sizeof(mem_types) / sizeof(mem_type_t);
const char *test_filter = NULL;
+ unsigned long hugepage_size;
bool list_only = false;
uffd_test_case_t *test;
mem_type_t *mem_type;
@@ -1745,6 +1766,8 @@ int main(int argc, char *argv[])
return KSFT_PASS;
}
+ hugepage_size = uffd_setup_hugetlb();
+
ksft_print_header();
ksft_set_plan(uffd_count_tests(n_tests, n_mems, test_filter));
@@ -1771,7 +1794,7 @@ int main(int argc, char *argv[])
uffd_test_case_ops = test->test_case_ops;
if (mem_type->mem_flag & (MEM_HUGETLB_PRIVATE | MEM_HUGETLB)) {
- gopts.page_size = default_huge_page_size();
+ gopts.page_size = hugepage_size;
if (gopts.page_size == 0) {
uffd_test_skip("huge page size is 0, feature missing?");
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 49/53] selftests/mm: uffd-wp-mremap: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (47 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 48/53] selftests/mm: uffd-unit-tests: add setup of HugeTLB pages Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 50/53] selftests/mm: va_high_addr_switch: " Mike Rapoport
` (3 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
uffd-wp-remap skips HugeTLB tests if there are no free huge pages
prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/uffd-wp-mremap.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/mm/uffd-wp-mremap.c b/tools/testing/selftests/mm/uffd-wp-mremap.c
index 9d67b11c2f28..f63fe02f404f 100644
--- a/tools/testing/selftests/mm/uffd-wp-mremap.c
+++ b/tools/testing/selftests/mm/uffd-wp-mremap.c
@@ -336,14 +336,14 @@ int main(int argc, char **argv)
struct thp_settings settings;
int i, j, plan = 0;
+ hugepage_save_settings(true, true);
+
pagesize = getpagesize();
nr_thpsizes = detect_thp_sizes(thpsizes, ARRAY_SIZE(thpsizes));
- nr_hugetlbsizes = detect_hugetlb_page_sizes(hugetlbsizes,
- ARRAY_SIZE(hugetlbsizes));
+ nr_hugetlbsizes = hugetlb_setup(1, hugetlbsizes, ARRAY_SIZE(hugetlbsizes));
/* If THP is supported, save THP settings and initially disable THP. */
if (nr_thpsizes) {
- thp_save_settings();
thp_read_settings(&settings);
for (i = 0; i < NR_ORDERS; i++) {
settings.hugepages[i].enabled = THP_NEVER;
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 50/53] selftests/mm: va_high_addr_switch: add setup of HugeTLB pages
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (48 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 49/53] selftests/mm: uffd-wp-mremap: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 51/53] selftests/mm: va_high_addr_switch.sh: drop huge pages setup Mike Rapoport
` (2 subsequent siblings)
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
va_high_addr_switch skips HugeTLB tests if there are no free huge pages
prepared by a wrapper script.
Add setup of HugeTLB pages to the test and make sure that the original
settings are restored on the test exit.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/va_high_addr_switch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/mm/va_high_addr_switch.c b/tools/testing/selftests/mm/va_high_addr_switch.c
index d42ad50eb2d3..4a764589f553 100644
--- a/tools/testing/selftests/mm/va_high_addr_switch.c
+++ b/tools/testing/selftests/mm/va_high_addr_switch.c
@@ -323,7 +323,7 @@ int main(int argc, char **argv)
if (!supported_arch())
ksft_exit_skip("Architecture not supported\n");
- if (argc == 2 && !strcmp(argv[1], "--run-hugetlb"))
+ if (hugetlb_setup_default(6))
run_hugetlb = true;
testcases_init();
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 51/53] selftests/mm: va_high_addr_switch.sh: drop huge pages setup
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (49 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 50/53] selftests/mm: va_high_addr_switch: " Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 52/53] selftests/mm: run_vmtests.sh: free memory if available memory is low Mike Rapoport
2026-04-06 14:17 ` [PATCH 53/53] selftests/mm: run_vmtests.sh: drop detection and setup of HugeTLB Mike Rapoport
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Since va_high_addr_switch takes care of setting up huge pages, there is
no need to set them up in the va_high_addr_switch.sh wrapper script.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
.../selftests/mm/va_high_addr_switch.sh | 39 +------------------
1 file changed, 1 insertion(+), 38 deletions(-)
diff --git a/tools/testing/selftests/mm/va_high_addr_switch.sh b/tools/testing/selftests/mm/va_high_addr_switch.sh
index 9492c2d72634..d66c0fd3cb4d 100755
--- a/tools/testing/selftests/mm/va_high_addr_switch.sh
+++ b/tools/testing/selftests/mm/va_high_addr_switch.sh
@@ -9,7 +9,6 @@
# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
-orig_nr_hugepages=0
skip()
{
@@ -77,43 +76,7 @@ check_test_requirements()
esac
}
-save_nr_hugepages()
-{
- orig_nr_hugepages=$(cat /proc/sys/vm/nr_hugepages)
-}
-
-restore_nr_hugepages()
-{
- echo "$orig_nr_hugepages" > /proc/sys/vm/nr_hugepages
-}
-
-setup_nr_hugepages()
-{
- local needpgs=$1
- while read -r name size unit; do
- if [ "$name" = "HugePages_Free:" ]; then
- freepgs="$size"
- break
- fi
- done < /proc/meminfo
- if [ "$freepgs" -ge "$needpgs" ]; then
- return
- fi
- local hpgs=$((orig_nr_hugepages + needpgs))
- echo $hpgs > /proc/sys/vm/nr_hugepages
-
- local nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
- if [ "$nr_hugepgs" != "$hpgs" ]; then
- restore_nr_hugepages
- skip "$0: no enough hugepages for testing"
- fi
-}
-
check_test_requirements
-save_nr_hugepages
-# The HugeTLB tests require 6 pages
-setup_nr_hugepages 6
-./va_high_addr_switch --run-hugetlb
+./va_high_addr_switch
retcode=$?
-restore_nr_hugepages
exit $retcode
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 52/53] selftests/mm: run_vmtests.sh: free memory if available memory is low
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (50 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 51/53] selftests/mm: va_high_addr_switch.sh: drop huge pages setup Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
2026-04-06 14:17 ` [PATCH 53/53] selftests/mm: run_vmtests.sh: drop detection and setup of HugeTLB Mike Rapoport
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Currently when running THP and HugeTLB tests, if HAVE_HUGEPAGES is set
run_test() drops caches, compacts memory and runs the test. But if
HAVE_HUGEPAGES is not set it skips the tests entirely, even if THP tests
have nothing to do with HAVE_HUGEPAGES.
Replace the check if HAVE_HUGEPAGES is set with a check of how much memory
is available. If there is less than 256 MB of available memory, drop caches
and run compaction and then continue to run a test regardless of
HAVE_HUGEPAGES value.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/run_vmtests.sh | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh
index b9e520194634..b42d19036182 100755
--- a/tools/testing/selftests/mm/run_vmtests.sh
+++ b/tools/testing/selftests/mm/run_vmtests.sh
@@ -99,6 +99,9 @@ EOF
exit 0
}
+mem_available_kb=$(awk '/MemAvailable/ {print $2}' /proc/meminfo)
+mem_available_Mb=$((mem_available_kb / 1024))
+
RUN_ALL=false
RUN_DESTRUCTIVE=false
TAP_PREFIX="# "
@@ -239,15 +242,12 @@ run_test() {
# On memory constrainted systems some tests can fail to allocate hugepages.
# perform some cleanup before the test for a higher success rate.
if [ ${CATEGORY} == "thp" -o ${CATEGORY} == "hugetlb" ]; then
- if [ "${HAVE_HUGEPAGES}" = "1" ]; then
- echo 3 > /proc/sys/vm/drop_caches
- sleep 2
- echo 1 > /proc/sys/vm/compact_memory
- sleep 2
- else
- echo "hugepages not supported" | tap_prefix
- skip=1
- fi
+ if (( $mem_available_Mb < 256 )); then
+ echo 3 > /proc/sys/vm/drop_caches
+ sleep 2
+ echo 1 > /proc/sys/vm/compact_memory
+ sleep 2
+ fi
fi
local test=$(pretty_name "$*")
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* [PATCH 53/53] selftests/mm: run_vmtests.sh: drop detection and setup of HugeTLB
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
` (51 preceding siblings ...)
2026-04-06 14:17 ` [PATCH 52/53] selftests/mm: run_vmtests.sh: free memory if available memory is low Mike Rapoport
@ 2026-04-06 14:17 ` Mike Rapoport
52 siblings, 0 replies; 61+ messages in thread
From: Mike Rapoport @ 2026-04-06 14:17 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Baolin Wang, Barry Song, Dev Jain, Jason Gunthorpe, John Hubbard,
Liam R. Howlett, Lance Yang, Leon Romanovsky, Lorenzo Stoakes,
Mark Brown, Michal Hocko, Mike Rapoport, Nico Pache, Peter Xu,
Ryan Roberts, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
Zi Yan, linux-kernel, linux-kselftest, linux-mm
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
All the tests that use HugeTLB can detect and setup HugeTLB pages on
their own.
Drop detection and setup of HugeTLB from run_vmtests.sh.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
tools/testing/selftests/mm/run_vmtests.sh | 128 ++--------------------
1 file changed, 9 insertions(+), 119 deletions(-)
diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh
index b42d19036182..7e0c379e7af4 100755
--- a/tools/testing/selftests/mm/run_vmtests.sh
+++ b/tools/testing/selftests/mm/run_vmtests.sh
@@ -157,60 +157,6 @@ run_gup_matrix() {
done
}
-# get huge pagesize and freepages from /proc/meminfo
-while read -r name size unit; do
- if [ "$name" = "HugePages_Free:" ]; then
- freepgs="$size"
- fi
- if [ "$name" = "Hugepagesize:" ]; then
- hpgsize_KB="$size"
- fi
-done < /proc/meminfo
-
-# Simple hugetlbfs tests have a hardcoded minimum requirement of
-# huge pages totaling 256MB (262144KB) in size. The userfaultfd
-# hugetlb test requires a minimum of 2 * nr_cpus huge pages. Take
-# both of these requirements into account and attempt to increase
-# number of huge pages available.
-nr_cpus=$(nproc)
-uffd_min_KB=$((hpgsize_KB * nr_cpus * 2))
-hugetlb_min_KB=$((256 * 1024))
-if [[ $uffd_min_KB -gt $hugetlb_min_KB ]]; then
- needmem_KB=$uffd_min_KB
-else
- needmem_KB=$hugetlb_min_KB
-fi
-
-# set proper nr_hugepages
-if [ -n "$freepgs" ] && [ -n "$hpgsize_KB" ]; then
- orig_nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
- needpgs=$((needmem_KB / hpgsize_KB))
- tries=2
- while [ "$tries" -gt 0 ] && [ "$freepgs" -lt "$needpgs" ]; do
- lackpgs=$((needpgs - freepgs))
- echo 3 > /proc/sys/vm/drop_caches
- if ! echo $((lackpgs + orig_nr_hugepgs)) > /proc/sys/vm/nr_hugepages; then
- echo "Please run this test as root"
- exit $ksft_skip
- fi
- while read -r name size unit; do
- if [ "$name" = "HugePages_Free:" ]; then
- freepgs=$size
- fi
- done < /proc/meminfo
- tries=$((tries - 1))
- done
- nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
- if [ "$freepgs" -lt "$needpgs" ]; then
- printf "Not enough huge pages available (%d < %d)\n" \
- "$freepgs" "$needpgs"
- fi
- HAVE_HUGEPAGES=1
-else
- echo "no hugetlbfs support in kernel?"
- HAVE_HUGEPAGES=0
-fi
-
# filter 64bit architectures
ARCH64STR="arm64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sparc64 x86_64"
if [ -z "$ARCH" ]; then
@@ -283,29 +229,13 @@ run_test() {
echo "TAP version 13" | tap_output
CATEGORY="hugetlb" run_test ./hugetlb-mmap
-
-shmmax=$(cat /proc/sys/kernel/shmmax)
-shmall=$(cat /proc/sys/kernel/shmall)
-echo 268435456 > /proc/sys/kernel/shmmax
-echo 4194304 > /proc/sys/kernel/shmall
CATEGORY="hugetlb" run_test ./hugetlb-shm
-echo "$shmmax" > /proc/sys/kernel/shmmax
-echo "$shmall" > /proc/sys/kernel/shmall
-
CATEGORY="hugetlb" run_test ./hugetlb-mremap
CATEGORY="hugetlb" run_test ./hugetlb-vmemmap
CATEGORY="hugetlb" run_test ./hugetlb-madvise
CATEGORY="hugetlb" run_test ./hugetlb_dio
-
-if [ "${HAVE_HUGEPAGES}" = "1" ]; then
- nr_hugepages_tmp=$(cat /proc/sys/vm/nr_hugepages)
- # For this test, we need one and just one huge page
- echo 1 > /proc/sys/vm/nr_hugepages
- CATEGORY="hugetlb" run_test ./hugetlb_fault_after_madv
- CATEGORY="hugetlb" run_test ./hugetlb_madv_vs_map
- # Restore the previous number of huge pages, since further tests rely on it
- echo "$nr_hugepages_tmp" > /proc/sys/vm/nr_hugepages
-fi
+CATEGORY="hugetlb" run_test ./hugetlb_fault_after_madv
+CATEGORY="hugetlb" run_test ./hugetlb_madv_vs_map
if test_selected "hugetlb"; then
echo "NOTE: These hugetlb tests provide minimal coverage. Use" | tap_prefix
@@ -332,44 +262,12 @@ CATEGORY="gup_test" run_test ./gup_longterm
CATEGORY="userfaultfd" run_test ./uffd-unit-tests
uffd_stress_bin=./uffd-stress
CATEGORY="userfaultfd" run_test ${uffd_stress_bin} anon 20 16
-# Hugetlb tests require source and destination huge pages. Pass in almost half
-# the size of the free pages we have, which is used for *each*. An adjustment
-# of (nr_parallel - 1) is done (see nr_parallel in uffd-stress.c) to have some
-# extra hugepages - this is done to prevent the test from failing by racily
-# reserving more hugepages than strictly required.
-# uffd-stress expects a region expressed in MiB, so we adjust
-# half_ufd_size_MB accordingly.
adjustment=$(( (31 < (nr_cpus - 1)) ? 31 : (nr_cpus - 1) ))
-half_ufd_size_MB=$((((freepgs - adjustment) * hpgsize_KB) / 1024 / 2))
-CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb "$half_ufd_size_MB" 32
-CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb-private "$half_ufd_size_MB" 32
+CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb 128 32
+CATEGORY="userfaultfd" run_test ${uffd_stress_bin} hugetlb-private 128 32
CATEGORY="userfaultfd" run_test ${uffd_stress_bin} shmem 20 16
CATEGORY="userfaultfd" run_test ${uffd_stress_bin} shmem-private 20 16
-# uffd-wp-mremap requires at least one page of each size.
-have_all_size_hugepgs=true
-declare -A nr_size_hugepgs
-for f in /sys/kernel/mm/hugepages/**/nr_hugepages; do
- old=$(cat $f)
- nr_size_hugepgs["$f"]="$old"
- if [ "$old" == 0 ]; then
- echo 1 > "$f"
- fi
- if [ $(cat "$f") == 0 ]; then
- have_all_size_hugepgs=false
- break
- fi
-done
-if $have_all_size_hugepgs; then
- CATEGORY="userfaultfd" run_test ./uffd-wp-mremap
-else
- echo "# SKIP ./uffd-wp-mremap"
-fi
-
-#cleanup
-for f in "${!nr_size_hugepgs[@]}"; do
- echo "${nr_size_hugepgs["$f"]}" > "$f"
-done
-echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages
+CATEGORY="userfaultfd" run_test ./uffd-wp-mremap
CATEGORY="compaction" run_test ./compaction_test
@@ -393,14 +291,11 @@ CATEGORY="mremap" run_test ./mremap_test
CATEGORY="hugetlb" run_test ./thuge-gen
CATEGORY="hugetlb" run_test ./charge_reserved_hugetlb.sh -cgroup-v2
CATEGORY="hugetlb" run_test ./hugetlb_reparenting_test.sh -cgroup-v2
+
if $RUN_DESTRUCTIVE; then
-nr_hugepages_tmp=$(cat /proc/sys/vm/nr_hugepages)
-enable_soft_offline=$(cat /proc/sys/vm/enable_soft_offline)
-echo 8 > /proc/sys/vm/nr_hugepages
-CATEGORY="hugetlb" run_test ./hugetlb-soft-offline
-echo "$nr_hugepages_tmp" > /proc/sys/vm/nr_hugepages
-echo "$enable_soft_offline" > /proc/sys/vm/enable_soft_offline
-CATEGORY="hugetlb" run_test ./hugetlb-read-hwpoison
+ CATEGORY="hugetlb" run_test ./hugetlb-soft-offline
+ echo "$enable_soft_offline" > /proc/sys/vm/enable_soft_offline
+ CATEGORY="hugetlb" run_test ./hugetlb-read-hwpoison
fi
if [ $VADDR64 -ne 0 ]; then
@@ -464,7 +359,6 @@ if [ -x ./protection_keys_64 ]
then
CATEGORY="pkey" run_test ./protection_keys_64
fi
-echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages
if [ -x ./soft-dirty ]
then
@@ -545,10 +439,6 @@ if [ -n "${LOADED_MOD}" ]; then
modprobe -r hwpoison_inject > /dev/null 2>&1
fi
-if [ "${HAVE_HUGEPAGES}" = 1 ]; then
- echo "$orig_nr_hugepgs" > /proc/sys/vm/nr_hugepages
-fi
-
echo "SUMMARY: PASS=${count_pass} SKIP=${count_skip} FAIL=${count_fail}" | tap_prefix
echo "1..${count_total}" | tap_output
--
2.53.0
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH 07/53] selftests/mm: hugetlb-shm: use kselftest framework
2026-04-06 14:16 ` [PATCH 07/53] selftests/mm: hugetlb-shm: use kselftest framework Mike Rapoport
@ 2026-04-06 14:27 ` Mark Brown
0 siblings, 0 replies; 61+ messages in thread
From: Mark Brown @ 2026-04-06 14:27 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, David Hildenbrand, Baolin Wang, Barry Song,
Dev Jain, Jason Gunthorpe, John Hubbard, Liam R. Howlett,
Lance Yang, Leon Romanovsky, Lorenzo Stoakes, Michal Hocko,
Nico Pache, Peter Xu, Ryan Roberts, Shuah Khan,
Suren Baghdasaryan, Vlastimil Babka, Zi Yan, linux-kernel,
linux-kselftest, linux-mm
[-- Attachment #1: Type: text/plain, Size: 425 bytes --]
On Mon, Apr 06, 2026 at 05:16:49PM +0300, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> Convert hugetlb-shm test to use kselftest framework for reporting and
> tracking successful and failing runs.
Reviewed-by: Mark Brown <broonie@kernel.org>
> + ksft_print_header();
> + ksft_set_plan(1);
> +
There's not a huge advantage where it's only one test but still, good
practice.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH 08/53] selftests/mm: hugetlb-vmemmap: use kselftest framework
2026-04-06 14:16 ` [PATCH 08/53] selftests/mm: hugetlb-vmemmap: " Mike Rapoport
@ 2026-04-06 14:40 ` Mark Brown
0 siblings, 0 replies; 61+ messages in thread
From: Mark Brown @ 2026-04-06 14:40 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, David Hildenbrand, Baolin Wang, Barry Song,
Dev Jain, Jason Gunthorpe, John Hubbard, Liam R. Howlett,
Lance Yang, Leon Romanovsky, Lorenzo Stoakes, Michal Hocko,
Nico Pache, Peter Xu, Ryan Roberts, Shuah Khan,
Suren Baghdasaryan, Vlastimil Babka, Zi Yan, linux-kernel,
linux-kselftest, linux-mm
[-- Attachment #1: Type: text/plain, Size: 226 bytes --]
On Mon, Apr 06, 2026 at 05:16:50PM +0300, Mike Rapoport wrote:
> Convert hugetlb-vmemmap test to use kselftest framework for reporting
> and tracking successful and failing runs.
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH 10/53] selftests/mm: hugetlb_madv_vs_map: use kselftest framework
2026-04-06 14:16 ` [PATCH 10/53] selftests/mm: hugetlb_madv_vs_map: " Mike Rapoport
@ 2026-04-06 15:06 ` Mark Brown
0 siblings, 0 replies; 61+ messages in thread
From: Mark Brown @ 2026-04-06 15:06 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, David Hildenbrand, Baolin Wang, Barry Song,
Dev Jain, Jason Gunthorpe, John Hubbard, Liam R. Howlett,
Lance Yang, Leon Romanovsky, Lorenzo Stoakes, Michal Hocko,
Nico Pache, Peter Xu, Ryan Roberts, Shuah Khan,
Suren Baghdasaryan, Vlastimil Babka, Zi Yan, linux-kernel,
linux-kselftest, linux-mm
[-- Attachment #1: Type: text/plain, Size: 293 bytes --]
On Mon, Apr 06, 2026 at 05:16:52PM +0300, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> Convert hugetlb_madv_vs_map test to use kselftest framework for
> reporting and tracking successful and failing runs.
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH 11/53] selftests/mm: hugetlb-read-hwpoison: use kselftest framework
2026-04-06 14:16 ` [PATCH 11/53] selftests/mm: hugetlb-read-hwpoison: " Mike Rapoport
@ 2026-04-06 16:19 ` Mark Brown
0 siblings, 0 replies; 61+ messages in thread
From: Mark Brown @ 2026-04-06 16:19 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, David Hildenbrand, Baolin Wang, Barry Song,
Dev Jain, Jason Gunthorpe, John Hubbard, Liam R. Howlett,
Lance Yang, Leon Romanovsky, Lorenzo Stoakes, Michal Hocko,
Nico Pache, Peter Xu, Ryan Roberts, Shuah Khan,
Suren Baghdasaryan, Vlastimil Babka, Zi Yan, linux-kernel,
linux-kselftest, linux-mm
[-- Attachment #1: Type: text/plain, Size: 295 bytes --]
On Mon, Apr 06, 2026 at 05:16:53PM +0300, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> Convert hugetlb-read-hwpoison test to use kselftest framework for
> reporting and tracking successful and failing runs.
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH 12/53] selftests/mm: khugepaged: group tests in an array
2026-04-06 14:16 ` [PATCH 12/53] selftests/mm: khugepaged: group tests in an array Mike Rapoport
@ 2026-04-06 16:49 ` Mark Brown
0 siblings, 0 replies; 61+ messages in thread
From: Mark Brown @ 2026-04-06 16:49 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, David Hildenbrand, Baolin Wang, Barry Song,
Dev Jain, Jason Gunthorpe, John Hubbard, Liam R. Howlett,
Lance Yang, Leon Romanovsky, Lorenzo Stoakes, Michal Hocko,
Nico Pache, Peter Xu, Ryan Roberts, Shuah Khan,
Suren Baghdasaryan, Vlastimil Babka, Zi Yan, linux-kernel,
linux-kselftest, linux-mm
[-- Attachment #1: Type: text/plain, Size: 935 bytes --]
On Mon, Apr 06, 2026 at 05:16:54PM +0300, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
> Currently khugepaged decides if a test can run using TEST() macro that
> checks what mem_ops and collapse_context are set by the command line
> arguments.
> For better compatibility with ksefltest framework, add an array of 'struct
> test_case's and redefine TEST() macro to conditionally add enabled tests to
> that array.
It would feel more idiomatic to skip rather than ignore the tests but
both approaches work in the end.
> + for (int i = 0; i < nr_test_cases; i++) {
> + struct test_case *t = &test_cases[i];
> +
> + exit_status = KSFT_PASS;
> + printf("\nRun test: %s: (%s:%s)\n", t->desc, t->ctx->name, t->ops->name);
> + t->fn(t->ctx, t->ops);
> + }
The exit_status handling here is a bit weird but it looks like the test
is a bit weird and I didn't spend time figuring out what the best thing
is.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH 15/53] selftests/mm: protection_keys: use descriptive test names in TAP output
2026-04-06 14:16 ` [PATCH 15/53] selftests/mm: protection_keys: use descriptive test names in TAP output Mike Rapoport
@ 2026-04-06 16:51 ` Mark Brown
0 siblings, 0 replies; 61+ messages in thread
From: Mark Brown @ 2026-04-06 16:51 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, David Hildenbrand, Baolin Wang, Barry Song,
Dev Jain, Jason Gunthorpe, John Hubbard, Liam R. Howlett,
Lance Yang, Leon Romanovsky, Lorenzo Stoakes, Michal Hocko,
Nico Pache, Peter Xu, Ryan Roberts, Shuah Khan,
Suren Baghdasaryan, Vlastimil Babka, Zi Yan, linux-kernel,
linux-kselftest, linux-mm
[-- Attachment #1: Type: text/plain, Size: 436 bytes --]
On Mon, Apr 06, 2026 at 05:16:57PM +0300, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> Replace the numeric test index in TAP output with the actual test
> function name.
This isn't TAP yet!
> Use a structure containing function pointer and its name rather than
> only the function pointer in the pkey_tests array.
Definitely a win though
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH 16/53] selftests/mm: protection_keys: use kselftest framework
2026-04-06 14:16 ` [PATCH 16/53] selftests/mm: protection_keys: use kselftest framework Mike Rapoport
@ 2026-04-06 17:02 ` Mark Brown
0 siblings, 0 replies; 61+ messages in thread
From: Mark Brown @ 2026-04-06 17:02 UTC (permalink / raw)
To: Mike Rapoport
Cc: Andrew Morton, David Hildenbrand, Baolin Wang, Barry Song,
Dev Jain, Jason Gunthorpe, John Hubbard, Liam R. Howlett,
Lance Yang, Leon Romanovsky, Lorenzo Stoakes, Michal Hocko,
Nico Pache, Peter Xu, Ryan Roberts, Shuah Khan,
Suren Baghdasaryan, Vlastimil Babka, Zi Yan, linux-kernel,
linux-kselftest, linux-mm
[-- Attachment #1: Type: text/plain, Size: 760 bytes --]
On Mon, Apr 06, 2026 at 05:16:58PM +0300, Mike Rapoport wrote:
> Adjust dprintf0() printouts to use "#" in the beginning of the line for
> TAP compatibility and add fflush(stdout) in the end of the test to
> ensure all the ksft_print_*() messages are really output.
We should probably add those flushes to the kselftest helpers (eg, the
one at the end of the program should be in ksft_finished()) if they're
needed. It ought to be redundant though, we do set stdout to be line
buffered in ksft_print_header() which means that either ksft_finished()
will print a line and flush or for abort_hooks() it's immediately before
we call exit() which should do the right thing anyway. If exit() isn't
flushing I'd not be optimistic that fflush() is going to work.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 61+ messages in thread
end of thread, other threads:[~2026-04-06 17:02 UTC | newest]
Thread overview: 61+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-06 14:16 [PATCH 00/53] selftests/mm: make MM selftests more CI friendly Mike Rapoport
2026-04-06 14:16 ` [PATCH 01/53] selftests/mm: hugetlb-read-hwpoison: add SIGBUS handler Mike Rapoport
2026-04-06 14:16 ` [PATCH 02/53] selftests/mm: khugepaged: enable collapse_single_pte_entry_compound for shmem Mike Rapoport
2026-04-06 14:16 ` [PATCH 03/53] selftests/mm: migration: don't assume hupe page is TWOMEG Mike Rapoport
2026-04-06 14:16 ` [PATCH 04/53] selftests/mm: run_vmtests.sh: don't gate THP and KSM tests on HAVE_HUGEPAGES Mike Rapoport
2026-04-06 14:16 ` [PATCH 05/53] selftests/mm: merge map_hugetlb into hugepage-mmap Mike Rapoport
2026-04-06 14:16 ` [PATCH 06/53] selftests/mm: rename hugepage-* tests to hugetlb-* Mike Rapoport
2026-04-06 14:16 ` [PATCH 07/53] selftests/mm: hugetlb-shm: use kselftest framework Mike Rapoport
2026-04-06 14:27 ` Mark Brown
2026-04-06 14:16 ` [PATCH 08/53] selftests/mm: hugetlb-vmemmap: " Mike Rapoport
2026-04-06 14:40 ` Mark Brown
2026-04-06 14:16 ` [PATCH 09/53] selftests/mm: hugetlb-madvise: " Mike Rapoport
2026-04-06 14:16 ` [PATCH 10/53] selftests/mm: hugetlb_madv_vs_map: " Mike Rapoport
2026-04-06 15:06 ` Mark Brown
2026-04-06 14:16 ` [PATCH 11/53] selftests/mm: hugetlb-read-hwpoison: " Mike Rapoport
2026-04-06 16:19 ` Mark Brown
2026-04-06 14:16 ` [PATCH 12/53] selftests/mm: khugepaged: group tests in an array Mike Rapoport
2026-04-06 16:49 ` Mark Brown
2026-04-06 14:16 ` [PATCH 13/53] selftests/mm: khugepaged: use ksefltest framework Mike Rapoport
2026-04-06 14:16 ` [PATCH 14/53] selftests/mm: ksm_tests: use kselftest framework Mike Rapoport
2026-04-06 14:16 ` [PATCH 15/53] selftests/mm: protection_keys: use descriptive test names in TAP output Mike Rapoport
2026-04-06 16:51 ` Mark Brown
2026-04-06 14:16 ` [PATCH 16/53] selftests/mm: protection_keys: use kselftest framework Mike Rapoport
2026-04-06 17:02 ` Mark Brown
2026-04-06 14:16 ` [PATCH 17/53] selftests/mm: uffd-stress: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 18/53] selftests/mm: uffd-unit-tests: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 19/53] selftests/mm: va_high_addr_switch: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 20/53] selftests/mm: add atexit() and signal handlers to thp_settings Mike Rapoport
2026-04-06 14:17 ` [PATCH 21/53] selftests/mm: rename thp_settings.[ch] to hugepage_settings.[ch] Mike Rapoport
2026-04-06 14:17 ` [PATCH 22/53] selftests/mm: move HugeTLB helpers to hugepage_settings Mike Rapoport
2026-04-06 14:17 ` [PATCH 23/53] selftests/mm: hugepage_settings: use unsigned long in detect_hugetlb_page_size Mike Rapoport
2026-04-06 14:17 ` [PATCH 24/53] selftests/mm: hugepage_settings: add APIs to get and set nr_hugepages Mike Rapoport
2026-04-06 14:17 ` [PATCH 25/53] selftests/mm: hugepage_settings: rename get_free_hugepages() Mike Rapoport
2026-04-06 14:17 ` [PATCH 26/53] selftests/mm: hugepage_settings: add APIs for HugeTLB setup and teardown Mike Rapoport
2026-04-06 14:17 ` [PATCH 27/53] selftests/mm: move read_file(), read_num() and write_num() to vm_util Mike Rapoport
2026-04-06 14:17 ` [PATCH 28/53] selftests/mm: vm_util: add helpers to set and restore shm limits Mike Rapoport
2026-04-06 14:17 ` [PATCH 29/53] selftests/mm: compaction_test: use HugeTLB helpers Mike Rapoport
2026-04-06 14:17 ` [PATCH 30/53] selftests/mm: cow: add setup of HugeTLB pages Mike Rapoport
2026-04-06 14:17 ` [PATCH 31/53] selftests/mm: gup_longterm: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 32/53] selftests/mm: gup_test: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 33/53] selftests/mm: hmm-tests: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 34/53] selftests/mm: hugepage_dio: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 35/53] selftests/mm: hugetlb_fault_after_madv: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 36/53] selftests/mm: hugetlb-madvise: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 37/53] selftests/mm: hugetlb_madv_vs_map: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 38/53] selftests/mm: hugetlb-mmap: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 39/53] selftests/mm: hugetlb-mremap: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 40/53] selftests/mm: hugetlb-shm: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 41/53] selftests/mm: hugetlb-soft-online: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 42/53] selftests/mm: hugetlb-vmemmap: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 43/53] selftests/mm: migration: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 44/53] selftests/mm: pagemap_ioctl: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 45/53] selftests/mm: protection_keys: use library code for HugeTLB setup Mike Rapoport
2026-04-06 14:17 ` [PATCH 46/53] selftests/mm: thuge-gen: add setup of HugeTLB pages Mike Rapoport
2026-04-06 14:17 ` [PATCH 47/53] selftests/mm: uffd-stress: use hugetlb_save and alloc huge pages Mike Rapoport
2026-04-06 14:17 ` [PATCH 48/53] selftests/mm: uffd-unit-tests: add setup of HugeTLB pages Mike Rapoport
2026-04-06 14:17 ` [PATCH 49/53] selftests/mm: uffd-wp-mremap: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 50/53] selftests/mm: va_high_addr_switch: " Mike Rapoport
2026-04-06 14:17 ` [PATCH 51/53] selftests/mm: va_high_addr_switch.sh: drop huge pages setup Mike Rapoport
2026-04-06 14:17 ` [PATCH 52/53] selftests/mm: run_vmtests.sh: free memory if available memory is low Mike Rapoport
2026-04-06 14:17 ` [PATCH 53/53] selftests/mm: run_vmtests.sh: drop detection and setup of HugeTLB Mike Rapoport
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox