* [PATCH 0/3] selftests/mm: assorted fixes for hmm-tests
@ 2026-05-04 9:11 Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 1/3] selftests/mm: allow PUD-level entries in compound testcase of hmm tests Aboorva Devarajan
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Aboorva Devarajan @ 2026-05-04 9:11 UTC (permalink / raw)
To: Andrew Morton, Shuah Khan, linux-mm, linux-kselftest
Cc: Sayali Patil, linux-kernel, Aboorva Devarajan
Hi all,
This series fixes a few issues in hmm-tests that show up when
page-size and huge-page configuration differ from the hardcoded
assumptions the tests were written for (PMD/THP sizing, default
hugepage size, and related cases).
It also includes a minor fix to exclusive_cow: the test ignored the
return value of fork(), so both parent and child ran the same teardown
path.
Please let us know if you have any comments.
Thanks,
Aboorva
Aboorva Devarajan (1):
selftests/mm: fix exclusive_cow test fork() handling
Sayali Patil (2):
selftests/mm: allow PUD-level entries in compound testcase of hmm
tests
selftests/mm: remove hardcoded THP sizing assumptions in hmm tests
tools/testing/selftests/mm/hmm-tests.c | 86 +++++++++++++++++---------
1 file changed, 58 insertions(+), 28 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] selftests/mm: allow PUD-level entries in compound testcase of hmm tests
2026-05-04 9:11 [PATCH 0/3] selftests/mm: assorted fixes for hmm-tests Aboorva Devarajan
@ 2026-05-04 9:11 ` Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 2/3] selftests/mm: remove hardcoded THP sizing assumptions in " Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 3/3] selftests/mm: fix exclusive_cow test fork() handling Aboorva Devarajan
2 siblings, 0 replies; 4+ messages in thread
From: Aboorva Devarajan @ 2026-05-04 9:11 UTC (permalink / raw)
To: Andrew Morton, Shuah Khan, linux-mm, linux-kselftest
Cc: Sayali Patil, linux-kernel, Aboorva Devarajan
From: Sayali Patil <sayalip@linux.ibm.com>
The HMM compound testcase currently assume only PMD-level
mappings and fail on systems when default_hugepagesz=1G is set.
Extend the checks to accept PUD-level protections as well,
avoiding false failures.
Fixes: e478425bec93 ("mm/hmm: add tests for hmm_pfn_to_map_order()")
Signed-off-by: Sayali Patil <sayalip@linux.ibm.com>
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
---
tools/testing/selftests/mm/hmm-tests.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/mm/hmm-tests.c b/tools/testing/selftests/mm/hmm-tests.c
index 77fb4c5d871b..6dc839866dfe 100644
--- a/tools/testing/selftests/mm/hmm-tests.c
+++ b/tools/testing/selftests/mm/hmm-tests.c
@@ -1599,8 +1599,8 @@ TEST_F(hmm2, snapshot)
}
/*
- * Test the hmm_range_fault() HMM_PFN_PMD flag for large pages that
- * should be mapped by a large page table entry.
+ * Test the hmm_range_fault() handling of large pages (PMD or PUD)
+ * that should be mapped by a large page table entry.
*/
TEST_F(hmm, compound)
{
@@ -1649,8 +1649,8 @@ TEST_F(hmm, compound)
/* Check what the device saw. */
m = buffer->mirror;
for (i = 0; i < npages; ++i)
- ASSERT_EQ(m[i], HMM_DMIRROR_PROT_WRITE |
- HMM_DMIRROR_PROT_PMD);
+ ASSERT_TRUE((m[i] == (HMM_DMIRROR_PROT_WRITE | HMM_DMIRROR_PROT_PMD)) ||
+ (m[i] == (HMM_DMIRROR_PROT_WRITE | HMM_DMIRROR_PROT_PUD)));
/* Make the region read-only. */
ret = mprotect(buffer->ptr, size, PROT_READ);
@@ -1664,8 +1664,8 @@ TEST_F(hmm, compound)
/* Check what the device saw. */
m = buffer->mirror;
for (i = 0; i < npages; ++i)
- ASSERT_EQ(m[i], HMM_DMIRROR_PROT_READ |
- HMM_DMIRROR_PROT_PMD);
+ ASSERT_TRUE((m[i] == (HMM_DMIRROR_PROT_READ | HMM_DMIRROR_PROT_PMD)) ||
+ (m[i] == (HMM_DMIRROR_PROT_READ | HMM_DMIRROR_PROT_PUD)));
munmap(buffer->ptr, buffer->size);
buffer->ptr = NULL;
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] selftests/mm: remove hardcoded THP sizing assumptions in hmm tests
2026-05-04 9:11 [PATCH 0/3] selftests/mm: assorted fixes for hmm-tests Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 1/3] selftests/mm: allow PUD-level entries in compound testcase of hmm tests Aboorva Devarajan
@ 2026-05-04 9:11 ` Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 3/3] selftests/mm: fix exclusive_cow test fork() handling Aboorva Devarajan
2 siblings, 0 replies; 4+ messages in thread
From: Aboorva Devarajan @ 2026-05-04 9:11 UTC (permalink / raw)
To: Andrew Morton, Shuah Khan, linux-mm, linux-kselftest
Cc: Sayali Patil, linux-kernel, Aboorva Devarajan
From: Sayali Patil <sayalip@linux.ibm.com>
migrate_partial_unmap_fault() and migrate_remap_fault() currently use
hardcoded offsets based on a 2MB PMD size. Likewise,
benchmark_thp_migration() assumes a fixed 2MB THP size when generating
test buffer sizes.
Derive offsets and test sizes from the runtime PMD page size returned
by read_pmd_pagesize(). This allows the tests to adapt correctly on
systems where PMD-sized THP differs from 2MB.
Also replace the fixed 1MB unmap size with a PMD-relative value derived
from the runtime PMD size.
Additionally, cap the maximum number of THPs used in benchmark tests to
avoid integer overflow when computing large buffer sizes. On systems
with larger PMD sizes, multiplying a fixed THP count can exceed
INT_MAX. Compute the maximum number of THPs at runtime as
(INT_MAX / thp_size) and use the smaller of that value and 128 when
constructing the largest benchmark buffer.
Fixes: 24c2c5b8ffbd ("selftests/mm/hmm-tests: partial unmap, mremap and anon_write tests")
Fixes: 271a7b2e3c13 ("selftests/mm/hmm-tests: new throughput tests including THP")
Signed-off-by: Sayali Patil <sayalip@linux.ibm.com>
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
---
tools/testing/selftests/mm/hmm-tests.c | 44 +++++++++++++++-----------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/tools/testing/selftests/mm/hmm-tests.c b/tools/testing/selftests/mm/hmm-tests.c
index 6dc839866dfe..1e5c1432ef6b 100644
--- a/tools/testing/selftests/mm/hmm-tests.c
+++ b/tools/testing/selftests/mm/hmm-tests.c
@@ -21,6 +21,7 @@
#include <strings.h>
#include <time.h>
#include <pthread.h>
+#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
@@ -2332,12 +2333,13 @@ TEST_F(hmm, migrate_partial_unmap_fault)
struct hmm_buffer *buffer;
unsigned long npages;
unsigned long size = read_pmd_pagesize();
+ unsigned long unmap_size = size / 2;
+ unsigned long offsets[] = { 0, size / 4, size / 2 };
unsigned long i;
void *old_ptr;
void *map;
int *ptr;
int ret, j, use_thp;
- int offsets[] = { 0, 512 * ONEKB, ONEMEG };
for (use_thp = 0; use_thp < 2; ++use_thp) {
for (j = 0; j < ARRAY_SIZE(offsets); ++j) {
@@ -2379,12 +2381,12 @@ TEST_F(hmm, migrate_partial_unmap_fault)
for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
ASSERT_EQ(ptr[i], i);
- munmap(buffer->ptr + offsets[j], ONEMEG);
+ munmap(buffer->ptr + offsets[j], unmap_size);
/* Fault pages back to system memory and check them. */
for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
if (i * sizeof(int) < offsets[j] ||
- i * sizeof(int) >= offsets[j] + ONEMEG)
+ i * sizeof(int) >= offsets[j] + unmap_size)
ASSERT_EQ(ptr[i], i);
buffer->ptr = old_ptr;
@@ -2398,12 +2400,12 @@ TEST_F(hmm, migrate_remap_fault)
struct hmm_buffer *buffer;
unsigned long npages;
unsigned long size = read_pmd_pagesize();
+ unsigned long offsets[] = { 0, size / 4, size / 2 };
unsigned long i;
void *old_ptr, *new_ptr = NULL;
void *map;
int *ptr;
int ret, j, use_thp, dont_unmap, before;
- int offsets[] = { 0, 512 * ONEKB, ONEMEG };
for (before = 0; before < 2; ++before) {
for (dont_unmap = 0; dont_unmap < 2; ++dont_unmap) {
@@ -2806,8 +2808,12 @@ static inline int run_migration_benchmark(int fd, int use_thp, size_t buffer_siz
TEST_F_TIMEOUT(hmm, benchmark_thp_migration, 120)
{
struct benchmark_results thp_results, regular_results;
- size_t thp_size = 2 * 1024 * 1024; /* 2MB - typical THP size */
+ size_t thp_size = read_pmd_pagesize();
int iterations = 5;
+ size_t max_thps, num_thps;
+
+ max_thps = INT_MAX / thp_size;
+ num_thps = (max_thps > 128) ? 128 : max_thps;
printf("\nHMM THP Migration Benchmark\n");
printf("---------------------------\n");
@@ -2815,23 +2821,23 @@ TEST_F_TIMEOUT(hmm, benchmark_thp_migration, 120)
/* Test different buffer sizes */
size_t test_sizes[] = {
- thp_size / 4, /* 512KB - smaller than THP */
- thp_size / 2, /* 1MB - half THP */
- thp_size, /* 2MB - single THP */
- thp_size * 2, /* 4MB - two THPs */
- thp_size * 4, /* 8MB - four THPs */
- thp_size * 8, /* 16MB - eight THPs */
- thp_size * 128, /* 256MB - one twenty eight THPs */
+ thp_size / 4, /* quarter THP */
+ thp_size / 2, /* half THP */
+ thp_size, /* single THP */
+ thp_size * 2, /* two THPs */
+ thp_size * 4, /* four THPs */
+ thp_size * 8, /* eight THPs */
+ thp_size * num_thps, /* max THPs without overflow */
};
static const char *const test_names[] = {
- "Small Buffer (512KB)",
- "Half THP Size (1MB)",
- "Single THP Size (2MB)",
- "Two THP Size (4MB)",
- "Four THP Size (8MB)",
- "Eight THP Size (16MB)",
- "One twenty eight THP Size (256MB)"
+ "Small Buffer",
+ "Half THP Size",
+ "Single THP Size",
+ "Two THP Size",
+ "Four THP Size",
+ "Eight THP Size",
+ "Large Buffer"
};
int num_tests = ARRAY_SIZE(test_sizes);
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] selftests/mm: fix exclusive_cow test fork() handling
2026-05-04 9:11 [PATCH 0/3] selftests/mm: assorted fixes for hmm-tests Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 1/3] selftests/mm: allow PUD-level entries in compound testcase of hmm tests Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 2/3] selftests/mm: remove hardcoded THP sizing assumptions in " Aboorva Devarajan
@ 2026-05-04 9:11 ` Aboorva Devarajan
2 siblings, 0 replies; 4+ messages in thread
From: Aboorva Devarajan @ 2026-05-04 9:11 UTC (permalink / raw)
To: Andrew Morton, Shuah Khan, linux-mm, linux-kselftest
Cc: Sayali Patil, linux-kernel, Aboorva Devarajan
The test ignores the return value of fork(), so both the parent and
the (newly created) child run the COW verification loops and then
call hmm_buffer_free() before returning into the kselftest harness,
which _exit()s each side. This duplicated teardown sequence has
been observed to manifest as a SIGSEGV in the test child, e.g.:
hmm-tests[360141]: segfault (11) at 0 nip 10006964 lr 1000ac3c code 1
in hmm-tests[6964,10000000+30000]
Fix this by adopting the same fork()-then-wait pattern already used
by the nearby anon_write_child / anon_write_child_shared tests in
this file: the child performs the COW verification and then _exit(0)s
so it does not run the test teardown, while the parent independently
verifies COW, waits for the child, and only then frees the buffer.
Fixes: b659baea75469 ("mm: selftests for exclusive device memory")
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
---
tools/testing/selftests/mm/hmm-tests.c | 30 +++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/mm/hmm-tests.c b/tools/testing/selftests/mm/hmm-tests.c
index 1e5c1432ef6b..c5000d53b604 100644
--- a/tools/testing/selftests/mm/hmm-tests.c
+++ b/tools/testing/selftests/mm/hmm-tests.c
@@ -1866,6 +1866,8 @@ TEST_F(hmm, exclusive_cow)
unsigned long i;
int *ptr;
int ret;
+ pid_t pid;
+ int status;
npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
ASSERT_NE(npages, 0);
@@ -1894,14 +1896,36 @@ TEST_F(hmm, exclusive_cow)
ASSERT_EQ(ret, 0);
ASSERT_EQ(buffer->cpages, npages);
- fork();
+ pid = fork();
+ if (pid == -1)
+ ASSERT_EQ(pid, 0);
- /* Fault pages back to system memory and check them. */
+ if (pid == 0) {
+ /*
+ * Child: fault pages back and verify COW, then _exit().
+ * On ASSERT failure the harness calls abort(); the parent
+ * reports it via the WIFEXITED/WEXITSTATUS checks below.
+ */
+ for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+ ASSERT_EQ(ptr[i]++, i);
+
+ for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
+ ASSERT_EQ(ptr[i], i + 1);
+
+ _exit(0);
+ }
+
+ /* Parent: also increment to verify COW works for both processes. */
for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
ASSERT_EQ(ptr[i]++, i);
for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
- ASSERT_EQ(ptr[i], i+1);
+ ASSERT_EQ(ptr[i], i + 1);
+
+ /* Parent: wait for child and then free the buffer. */
+ ASSERT_EQ(waitpid(pid, &status, 0), pid);
+ ASSERT_TRUE(WIFEXITED(status));
+ ASSERT_EQ(WEXITSTATUS(status), 0);
hmm_buffer_free(buffer);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-05-04 9:11 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-04 9:11 [PATCH 0/3] selftests/mm: assorted fixes for hmm-tests Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 1/3] selftests/mm: allow PUD-level entries in compound testcase of hmm tests Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 2/3] selftests/mm: remove hardcoded THP sizing assumptions in " Aboorva Devarajan
2026-05-04 9:11 ` [PATCH 3/3] selftests/mm: fix exclusive_cow test fork() handling Aboorva Devarajan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox