selftests/mm: remove hardcoded THP sizing assumptions in hmm tests

migrate_partial_unmap_fault() and migrate_remap_fault() use hardcoded
offsets based on a 2MB PMD size.  Similarly, 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().  If unavailable, fall back to TWOMEG.  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.

On systems with larger PMD sizes, computed test buffer sizes can exceed
INT_MAX.  Skip such test cases to avoid overflow.

Link: https://lore.kernel.org/20260611034102.1030738-3-aboorvad@linux.ibm.com
Fixes: 24c2c5b8ff ("selftests/mm/hmm-tests: partial unmap, mremap and anon_write tests")
Fixes: 271a7b2e3c ("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>
Acked-by: Balbir Singh <balbirs@nvidia.com>
Cc: Alex Sierra <alex.sierra@amd.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Ralph Campbell <rcampbell@nvidia.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Sayali Patil 2026-06-11 09:11:01 +05:30 committed by Andrew Morton
parent 224ed0e019
commit 8edb0e769c

View File

@ -22,6 +22,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>
@ -2380,12 +2381,21 @@ TEST_F(hmm, migrate_partial_unmap_fault)
struct hmm_buffer *buffer;
unsigned long npages;
unsigned long size = read_pmd_pagesize();
unsigned long unmap_size;
unsigned long offsets[3];
unsigned long i;
void *old_ptr;
void *map;
int *ptr;
int ret, j, use_thp;
int offsets[] = { 0, 512 * ONEKB, ONEMEG };
if (!size)
size = TWOMEG;
unmap_size = size / 2;
offsets[0] = 0;
offsets[1] = size / 4;
offsets[2] = size / 2;
for (use_thp = 0; use_thp < 2; ++use_thp) {
for (j = 0; j < ARRAY_SIZE(offsets); ++j) {
@ -2427,12 +2437,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;
@ -2446,12 +2456,19 @@ TEST_F(hmm, migrate_remap_fault)
struct hmm_buffer *buffer;
unsigned long npages;
unsigned long size = read_pmd_pagesize();
unsigned long offsets[3];
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 };
if (!size)
size = TWOMEG;
offsets[0] = 0;
offsets[1] = size / 4;
offsets[2] = size / 2;
for (before = 0; before < 2; ++before) {
for (dont_unmap = 0; dont_unmap < 2; ++dont_unmap) {
@ -2854,38 +2871,45 @@ 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;
if (!thp_size)
thp_size = TWOMEG;
printf("\nHMM THP Migration Benchmark\n");
printf("---------------------------\n");
printf("System page size: %ld bytes\n", sysconf(_SC_PAGESIZE));
/* 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 * 128, /* one twenty eight THPs */
};
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",
"One twenty eight THP Size"
};
int num_tests = ARRAY_SIZE(test_sizes);
/* Run all tests */
for (int i = 0; i < num_tests; i++) {
/* Skip test sizes exceeding INT_MAX to avoid overflow */
if (test_sizes[i] > INT_MAX)
break;
/* Test with THP */
ASSERT_EQ(run_migration_benchmark(self->fd, 1, test_sizes[i],
iterations, &thp_results), 0);