* [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro
@ 2026-09-07 8:15 Yeoreum Yun
2026-09-07 11:40 ` Sarthak Sharma
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Yeoreum Yun @ 2026-09-07 8:15 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: akpm, david, ljs, liam, vbabka, rppt, surenb, mhocko, shuah, ziy,
baolin.wang, nico.pache, ryan.roberts, dev.jain, baohua,
lance.yang, usama.arif, kas, sarthak.sharma, Yeoreum Yun
HPAGE_SIZE and HPAGE_SHIFT macro is written based on the 4KB PAGE_SIZE.
When this macro is used in some test, test result would be strange in
the system where PAGE_SIZE is more then 4KB.
Here is the example with transhuge-stress test with 16KB PAGE_SIZE:
transhuge-stress: allocate 61073 transhuge pages, using 122146 MiB virtual memory and 1908 MiB of ram
3.292 s/loop, 0.054 ms/page, 37106.002 MiB/s 2566 succeed, 58507 failed, 2566 different pages
0.591 s/loop, 0.010 ms/page, 206850.792 MiB/s 0 succeed, 61073 failed, 0 different pages
0.527 s/loop, 0.009 ms/page, 231895.107 MiB/s 0 succeed, 61073 failed, 0 different pages
0.527 s/loop, 0.009 ms/page, 231839.704 MiB/s 0 succeed, 61073 failed, 0 different pages
0.528 s/loop, 0.009 ms/page, 231544.782 MiB/s 0 succeed, 61073 failed, 0 different pages
0.528 s/loop, 0.009 ms/page, 231462.074 MiB/s 0 succeed, 61073 failed, 0 different pages
0.527 s/loop, 0.009 ms/page, 231770.300 MiB/s 0 succeed, 61073 failed, 0 different pages
...
ok 1 Completed
Remove the HPAGE_SIZE and HPAGE_SHIFT macros and introduce pmd_page_shift()
helper to get the HPAGE_SHIFT properly. For HPAGE_SIZE, use pre-existing
helper, read_pmd_pagesize().
Also, run the KSM_MERGE_TIME_HUGE_PAGES test with a size of 512 MiB,
which is the least common multiple of the PMD sizes for 4 KiB, 16 KiB,
and 64 KiB base pages. Since allocate_transhuge() allocates mappings in
PMD-sized units, the test may fail with the previous size of 100 MiB,
which is not a multiple of the PMD size when the base page size is
16 KiB or 64 KiB.
After this patch, output of transhuge-stress:
transhuge-stress: allocate 3817 transhuge pages, using 122146 MiB virtual memory and 119 MiB of ram
2.558 s/loop, 0.670 ms/page, 47755.759 MiB/s 2585 succeed, 1232 failed, 2585 different pages
2.640 s/loop, 0.692 ms/page, 46268.432 MiB/s 2585 succeed, 1232 failed, 2585 different pages
2.635 s/loop, 0.690 ms/page, 46360.298 MiB/s 2585 succeed, 1232 failed, 2585 different pages
2.782 s/loop, 0.729 ms/page, 43899.795 MiB/s 2616 succeed, 1201 failed, 2616 different pages
2.692 s/loop, 0.705 ms/page, 45380.876 MiB/s 2627 succeed, 1190 failed, 2627 different pages
2.612 s/loop, 0.684 ms/page, 46765.812 MiB/s 2628 succeed, 1189 failed, 2628 different pages
2.683 s/loop, 0.703 ms/page, 45520.990 MiB/s 2630 succeed, 1187 failed, 2630 different pages
2.727 s/loop, 0.714 ms/page, 44789.321 MiB/s 2631 succeed, 1186 failed, 2631 different pages
...
ok 1 Completed
Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
Chnage in v2:
- rename hpage_* to pmd_page_*
- Link to v1: https://lore.kernel.org/all/20260902175611.1241118-1-yeoreum.yun@arm.com/#t
---
tools/testing/selftests/mm/guard-regions.c | 11 ++++--
tools/testing/selftests/mm/ksm_tests.c | 16 +++++----
tools/testing/selftests/mm/run_vmtests.sh | 4 +--
tools/testing/selftests/mm/transhuge-stress.c | 25 +++++++------
tools/testing/selftests/mm/vm_util.c | 36 ++++++++++++++++---
tools/testing/selftests/mm/vm_util.h | 9 ++---
6 files changed, 71 insertions(+), 30 deletions(-)
diff --git a/tools/testing/selftests/mm/guard-regions.c b/tools/testing/selftests/mm/guard-regions.c
index 5c8ec3ca75d7..e57cc7e39e41 100644
--- a/tools/testing/selftests/mm/guard-regions.c
+++ b/tools/testing/selftests/mm/guard-regions.c
@@ -2195,14 +2195,21 @@ TEST_F(guard_regions, pagemap_scan)
TEST_F(guard_regions, collapse)
{
const unsigned long page_size = self->page_size;
- const unsigned long size = 2 * HPAGE_SIZE;
- const unsigned long num_pages = size / page_size;
+ const uint64_t hpage_size = read_pmd_pagesize();
+ unsigned long size;
+ unsigned long num_pages;
char *ptr;
int i;
if (!thp_available())
SKIP(return, "Transparent Hugepages not available\n");
+ if (!hpage_size)
+ ksft_exit_fail_msg("reading hpage_size failed\n");
+
+ size = 2 * hpage_size;
+ num_pages = size / page_size;
+
/* Need file to be correct size for tests for non-anon. */
if (variant->backing != ANON_BACKED)
ASSERT_EQ(ftruncate(self->fd, size), 0);
diff --git a/tools/testing/selftests/mm/ksm_tests.c b/tools/testing/selftests/mm/ksm_tests.c
index 5fd7792a0d47..ef27ce467b8c 100644
--- a/tools/testing/selftests/mm/ksm_tests.c
+++ b/tools/testing/selftests/mm/ksm_tests.c
@@ -521,19 +521,23 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot,
struct timespec start_time, end_time;
unsigned long scan_time_ns;
int pagemap_fd, n_normal_pages, n_huge_pages;
+ const uint64_t hpage_size = read_pmd_pagesize();
if (!thp_is_enabled()) {
ksft_print_msg("Transparent Hugepages not available\n");
return KSFT_SKIP;
}
+ if (!hpage_size)
+ ksft_exit_fail_msg("reading hpage_size failed\n");
+
map_size *= MB;
size_t len = map_size;
- len -= len % HPAGE_SIZE;
- map_ptr_orig = mmap(NULL, len + HPAGE_SIZE, PROT_READ | PROT_WRITE,
+ len -= len % hpage_size;
+ map_ptr_orig = mmap(NULL, len + hpage_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE, -1, 0);
- map_ptr = map_ptr_orig + HPAGE_SIZE - (uintptr_t)map_ptr_orig % HPAGE_SIZE;
+ map_ptr = map_ptr_orig + hpage_size - (uintptr_t)map_ptr_orig % hpage_size;
if (map_ptr_orig == MAP_FAILED)
err(2, "initial mmap");
@@ -547,7 +551,7 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot,
n_normal_pages = 0;
n_huge_pages = 0;
- for (void *p = map_ptr; p < map_ptr + len; p += HPAGE_SIZE) {
+ for (void *p = map_ptr; p < map_ptr + len; p += hpage_size) {
if (allocate_transhuge(p, pagemap_fd) < 0)
n_normal_pages++;
else
@@ -578,11 +582,11 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot,
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);
+ munmap(map_ptr_orig, len + hpage_size);
return KSFT_PASS;
err_out:
- munmap(map_ptr_orig, len + HPAGE_SIZE);
+ munmap(map_ptr_orig, len + hpage_size);
return KSFT_FAIL;
}
diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh
index d09f9f6a384e..24aa1de27c25 100755
--- a/tools/testing/selftests/mm/run_vmtests.sh
+++ b/tools/testing/selftests/mm/run_vmtests.sh
@@ -360,8 +360,8 @@ fi
CATEGORY="memfd_secret" run_test ./memfd_secret
fi
-# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100
-CATEGORY="ksm" run_test ./ksm_tests -H -s 100
+# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 512
+CATEGORY="ksm" run_test ./ksm_tests -H -s 512
# 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
diff --git a/tools/testing/selftests/mm/transhuge-stress.c b/tools/testing/selftests/mm/transhuge-stress.c
index 8eb0c5630e7e..9cd9790224db 100644
--- a/tools/testing/selftests/mm/transhuge-stress.c
+++ b/tools/testing/selftests/mm/transhuge-stress.c
@@ -35,12 +35,17 @@ int main(int argc, char **argv)
size_t map_len;
int pagemap_fd;
int duration = 0;
+ const uint64_t hpage_size = read_pmd_pagesize();
+ const uint64_t hpage_shift = pmd_page_shift();
ksft_print_header();
if (!thp_is_enabled())
ksft_exit_skip("Transparent Hugepages not available\n");
+ if (!hpage_size || !hpage_shift)
+ ksft_exit_fail_msg("reading hpage_size failed\n");
+
ram = sysconf(_SC_PHYS_PAGES);
if (ram > SIZE_MAX / psize() / 4)
ram = SIZE_MAX / 4;
@@ -70,23 +75,23 @@ int main(int argc, char **argv)
}
warnx("allocate %zd transhuge pages, using %zd MiB virtual memory"
- " and %zd MiB of ram", len >> HPAGE_SHIFT, len >> 20,
- ram >> (20 + HPAGE_SHIFT - pshift() - 1));
+ " and %zd MiB of ram", len >> hpage_shift, len >> 20,
+ ram >> (20 + hpage_shift - pshift() - 1));
pagemap_fd = open("/proc/self/pagemap", O_RDONLY);
if (pagemap_fd < 0)
ksft_exit_fail_msg("open pagemap\n");
- len -= len % HPAGE_SIZE;
- ptr = mmap(NULL, len + HPAGE_SIZE, PROT_RW, mmap_flags, backing_fd, 0);
+ len -= len % hpage_size;
+ ptr = mmap(NULL, len + hpage_size, PROT_RW, mmap_flags, backing_fd, 0);
if (ptr == MAP_FAILED)
ksft_exit_fail_msg("initial mmap");
- ptr += HPAGE_SIZE - (uintptr_t)ptr % HPAGE_SIZE;
+ ptr += hpage_size - (uintptr_t)ptr % hpage_size;
if (madvise(ptr, len, MADV_HUGEPAGE))
ksft_exit_fail_msg("MADV_HUGEPAGE");
- map_len = ram >> (HPAGE_SHIFT - 1);
+ map_len = ram >> (hpage_shift - 1);
map = malloc(map_len);
if (!map)
ksft_exit_fail_msg("map malloc\n");
@@ -99,7 +104,7 @@ int main(int argc, char **argv)
memset(map, 0, map_len);
clock_gettime(CLOCK_MONOTONIC, &a);
- for (p = ptr; p < ptr + len; p += HPAGE_SIZE) {
+ for (p = ptr; p < ptr + len; p += hpage_size) {
int64_t pfn;
pfn = allocate_transhuge(p, pagemap_fd);
@@ -107,7 +112,7 @@ int main(int argc, char **argv)
if (pfn < 0) {
nr_failed++;
} else {
- size_t idx = pfn >> (HPAGE_SHIFT - pshift());
+ size_t idx = pfn >> (hpage_shift - pshift());
nr_succeed++;
if (idx >= map_len) {
@@ -123,7 +128,7 @@ int main(int argc, char **argv)
}
/* split transhuge page, keep last page */
- if (madvise(p, HPAGE_SIZE - psize(), MADV_DONTNEED))
+ if (madvise(p, hpage_size - psize(), MADV_DONTNEED))
ksft_exit_fail_msg("MADV_DONTNEED");
}
clock_gettime(CLOCK_MONOTONIC, &b);
@@ -131,7 +136,7 @@ int main(int argc, char **argv)
ksft_print_msg("%.3f s/loop, %.3f ms/page, %10.3f MiB/s\t"
"%4d succeed, %4d failed, %4d different pages\n",
- s, s * 1000 / (len >> HPAGE_SHIFT), len / s / (1 << 20),
+ s, s * 1000 / (len >> hpage_shift), len / s / (1 << 20),
nr_succeed, nr_failed, nr_pages);
if (duration > 0 && b.tv_sec - start.tv_sec >= duration) {
diff --git a/tools/testing/selftests/mm/vm_util.c b/tools/testing/selftests/mm/vm_util.c
index 4821a3563036..f75bf0bacd18 100644
--- a/tools/testing/selftests/mm/vm_util.c
+++ b/tools/testing/selftests/mm/vm_util.c
@@ -21,6 +21,8 @@
unsigned int __page_size;
unsigned int __page_shift;
+uint64_t __pmd_page_size;
+uint64_t __pmd_page_shift;
uint64_t pagemap_get_entry(int fd, char *start)
{
@@ -161,6 +163,9 @@ uint64_t read_pmd_pagesize(void)
char buf[20];
ssize_t num_read;
+ if (__pmd_page_size)
+ return __pmd_page_size;
+
fd = open(PMD_SIZE_FILE_PATH, O_RDONLY);
if (fd == -1)
return 0;
@@ -173,7 +178,25 @@ uint64_t read_pmd_pagesize(void)
buf[num_read] = '\0';
close(fd);
- return strtoul(buf, NULL, 10);
+ __pmd_page_size = strtoul(buf, NULL, 10);
+
+ return __pmd_page_size;
+}
+
+uint64_t pmd_page_shift(void)
+{
+ if (__pmd_page_shift)
+ return __pmd_page_shift;
+
+ if (!__pmd_page_size)
+ __pmd_page_size = read_pmd_pagesize();
+
+ if (!__pmd_page_size)
+ return 0;
+
+ __pmd_page_shift = (ffsl(__pmd_page_size) - 1);
+
+ return __pmd_page_shift;
}
unsigned long rss_anon(void)
@@ -452,14 +475,19 @@ bool check_huge_shmem(void *addr, size_t len, int nr_hpages, uint64_t hpage_size
int64_t allocate_transhuge(void *ptr, int pagemap_fd)
{
uint64_t ent[2];
+ const uint64_t hpage_size = read_pmd_pagesize();
+ const uint64_t hpage_shift = pmd_page_shift();
+
+ if (!hpage_size || !hpage_shift)
+ return -1;
/* drop pmd */
- if (mmap(ptr, HPAGE_SIZE, PROT_READ | PROT_WRITE,
+ if (mmap(ptr, hpage_size, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_ANONYMOUS |
MAP_NORESERVE | MAP_PRIVATE, -1, 0) != ptr)
ksft_exit_fail_msg("mmap transhuge\n");
- if (madvise(ptr, HPAGE_SIZE, MADV_HUGEPAGE))
+ if (madvise(ptr, hpage_size, MADV_HUGEPAGE))
ksft_exit_fail_msg("MADV_HUGEPAGE\n");
/* allocate transparent huge page */
@@ -471,7 +499,7 @@ int64_t allocate_transhuge(void *ptr, int pagemap_fd)
if (PAGEMAP_PRESENT(ent[0]) && PAGEMAP_PRESENT(ent[1]) &&
PAGEMAP_PFN(ent[0]) + 1 == PAGEMAP_PFN(ent[1]) &&
- !(PAGEMAP_PFN(ent[0]) & ((1 << (HPAGE_SHIFT - pshift())) - 1)))
+ !(PAGEMAP_PFN(ent[0]) & ((1 << (hpage_shift - pshift())) - 1)))
return PAGEMAP_PFN(ent[0]);
return -1;
diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h
index 9a49af88702e..1d2608c1ad08 100644
--- a/tools/testing/selftests/mm/vm_util.h
+++ b/tools/testing/selftests/mm/vm_util.h
@@ -31,6 +31,8 @@
extern unsigned int __page_size;
extern unsigned int __page_shift;
+extern uint64_t __pmd_page_size;
+extern uint64_t __pmd_page_shift;
/*
* Represents an open fd and PROCMAP_QUERY state for binary (via ioctl)
@@ -89,6 +91,7 @@ unsigned long pagemap_get_pfn(int fd, char *start);
void clear_softdirty(void);
bool check_for_pattern(FILE *fp, const char *pattern, char *buf, size_t len);
uint64_t read_pmd_pagesize(void);
+uint64_t pmd_page_shift(void);
unsigned long rss_anon(void);
bool check_huge_anon(void *addr, size_t len, int nr_hpages, uint64_t hpage_size);
bool check_huge_file(void *addr, size_t len, int nr_hpages, uint64_t hpage_size);
@@ -157,12 +160,6 @@ int ksm_stop(void);
int get_hardware_corrupted_size(unsigned long *val);
int unpoison_memory(unsigned long pfn);
-/*
- * On ppc64 this will only work with radix 2M hugepage size
- */
-#define HPAGE_SHIFT 21
-#define HPAGE_SIZE (1 << HPAGE_SHIFT)
-
#define PAGEMAP_PRESENT(ent) (((ent) & (1ull << 63)) != 0)
#define PAGEMAP_PFN(ent) ((ent) & ((1ull << 55) - 1))
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro 2026-09-07 8:15 [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro Yeoreum Yun @ 2026-09-07 11:40 ` Sarthak Sharma 2026-09-07 12:46 ` Lorenzo Stoakes (ARM) 2026-09-07 14:36 ` David Hildenbrand (Arm) 2 siblings, 0 replies; 8+ messages in thread From: Sarthak Sharma @ 2026-09-07 11:40 UTC (permalink / raw) To: Yeoreum Yun, linux-mm, linux-kselftest Cc: akpm, david, ljs, liam, vbabka, rppt, surenb, mhocko, shuah, ziy, baolin.wang, nico.pache, ryan.roberts, dev.jain, baohua, lance.yang, usama.arif, kas Hi Yeoreum! On 9/7/26 1:45 PM, Yeoreum Yun wrote: > HPAGE_SIZE and HPAGE_SHIFT macro is written based on the 4KB PAGE_SIZE. > When this macro is used in some test, test result would be strange in > the system where PAGE_SIZE is more then 4KB. > > Here is the example with transhuge-stress test with 16KB PAGE_SIZE: > > transhuge-stress: allocate 61073 transhuge pages, using 122146 MiB virtual memory and 1908 MiB of ram > 3.292 s/loop, 0.054 ms/page, 37106.002 MiB/s 2566 succeed, 58507 failed, 2566 different pages > 0.591 s/loop, 0.010 ms/page, 206850.792 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.527 s/loop, 0.009 ms/page, 231895.107 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.527 s/loop, 0.009 ms/page, 231839.704 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.528 s/loop, 0.009 ms/page, 231544.782 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.528 s/loop, 0.009 ms/page, 231462.074 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.527 s/loop, 0.009 ms/page, 231770.300 MiB/s 0 succeed, 61073 failed, 0 different pages > ... > ok 1 Completed > > Remove the HPAGE_SIZE and HPAGE_SHIFT macros and introduce pmd_page_shift() > helper to get the HPAGE_SHIFT properly. For HPAGE_SIZE, use pre-existing > helper, read_pmd_pagesize(). > > Also, run the KSM_MERGE_TIME_HUGE_PAGES test with a size of 512 MiB, > which is the least common multiple of the PMD sizes for 4 KiB, 16 KiB, > and 64 KiB base pages. Since allocate_transhuge() allocates mappings in > PMD-sized units, the test may fail with the previous size of 100 MiB, > which is not a multiple of the PMD size when the base page size is > 16 KiB or 64 KiB. > > After this patch, output of transhuge-stress: > > transhuge-stress: allocate 3817 transhuge pages, using 122146 MiB virtual memory and 119 MiB of ram > 2.558 s/loop, 0.670 ms/page, 47755.759 MiB/s 2585 succeed, 1232 failed, 2585 different pages > 2.640 s/loop, 0.692 ms/page, 46268.432 MiB/s 2585 succeed, 1232 failed, 2585 different pages > 2.635 s/loop, 0.690 ms/page, 46360.298 MiB/s 2585 succeed, 1232 failed, 2585 different pages > 2.782 s/loop, 0.729 ms/page, 43899.795 MiB/s 2616 succeed, 1201 failed, 2616 different pages > 2.692 s/loop, 0.705 ms/page, 45380.876 MiB/s 2627 succeed, 1190 failed, 2627 different pages > 2.612 s/loop, 0.684 ms/page, 46765.812 MiB/s 2628 succeed, 1189 failed, 2628 different pages > 2.683 s/loop, 0.703 ms/page, 45520.990 MiB/s 2630 succeed, 1187 failed, 2630 different pages > 2.727 s/loop, 0.714 ms/page, 44789.321 MiB/s 2631 succeed, 1186 failed, 2631 different pages > ... > ok 1 Completed > > Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > --- > Chnage in v2: > - rename hpage_* to pmd_page_* > - Link to v1: https://lore.kernel.org/all/20260902175611.1241118-1-yeoreum.yun@arm.com/#t Thanks for accepting the suggestion to rename :) I've tested this patch on 16kB and 64kB machines. Before the patch, transhuge_stress attempted the same number of allocations irrespective of the page size, since HPAGE_SIZE was hardcoded. After applying the patch, it correctly reads PMD size and calculates the attempts accordingly. Tested-by: Sarthak Sharma <sarthak.sharma@arm.com> IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro 2026-09-07 8:15 [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro Yeoreum Yun 2026-09-07 11:40 ` Sarthak Sharma @ 2026-09-07 12:46 ` Lorenzo Stoakes (ARM) 2026-09-07 14:36 ` David Hildenbrand (Arm) 2 siblings, 0 replies; 8+ messages in thread From: Lorenzo Stoakes (ARM) @ 2026-09-07 12:46 UTC (permalink / raw) To: Yeoreum Yun Cc: linux-mm, linux-kselftest, akpm, david, liam, vbabka, rppt, surenb, mhocko, shuah, ziy, baolin.wang, nico.pache, ryan.roberts, dev.jain, baohua, lance.yang, usama.arif, kas, sarthak.sharma On Mon, Sep 07, 2026 at 09:15:08AM +0100, Yeoreum Yun wrote: > HPAGE_SIZE and HPAGE_SHIFT macro is written based on the 4KB PAGE_SIZE. > When this macro is used in some test, test result would be strange in > the system where PAGE_SIZE is more then 4KB. > > Here is the example with transhuge-stress test with 16KB PAGE_SIZE: > > transhuge-stress: allocate 61073 transhuge pages, using 122146 MiB virtual memory and 1908 MiB of ram > 3.292 s/loop, 0.054 ms/page, 37106.002 MiB/s 2566 succeed, 58507 failed, 2566 different pages > 0.591 s/loop, 0.010 ms/page, 206850.792 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.527 s/loop, 0.009 ms/page, 231895.107 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.527 s/loop, 0.009 ms/page, 231839.704 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.528 s/loop, 0.009 ms/page, 231544.782 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.528 s/loop, 0.009 ms/page, 231462.074 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.527 s/loop, 0.009 ms/page, 231770.300 MiB/s 0 succeed, 61073 failed, 0 different pages > ... > ok 1 Completed > > Remove the HPAGE_SIZE and HPAGE_SHIFT macros and introduce pmd_page_shift() > helper to get the HPAGE_SHIFT properly. For HPAGE_SIZE, use pre-existing > helper, read_pmd_pagesize(). > > Also, run the KSM_MERGE_TIME_HUGE_PAGES test with a size of 512 MiB, > which is the least common multiple of the PMD sizes for 4 KiB, 16 KiB, > and 64 KiB base pages. Since allocate_transhuge() allocates mappings in > PMD-sized units, the test may fail with the previous size of 100 MiB, > which is not a multiple of the PMD size when the base page size is > 16 KiB or 64 KiB. > > After this patch, output of transhuge-stress: > > transhuge-stress: allocate 3817 transhuge pages, using 122146 MiB virtual memory and 119 MiB of ram > 2.558 s/loop, 0.670 ms/page, 47755.759 MiB/s 2585 succeed, 1232 failed, 2585 different pages > 2.640 s/loop, 0.692 ms/page, 46268.432 MiB/s 2585 succeed, 1232 failed, 2585 different pages > 2.635 s/loop, 0.690 ms/page, 46360.298 MiB/s 2585 succeed, 1232 failed, 2585 different pages > 2.782 s/loop, 0.729 ms/page, 43899.795 MiB/s 2616 succeed, 1201 failed, 2616 different pages > 2.692 s/loop, 0.705 ms/page, 45380.876 MiB/s 2627 succeed, 1190 failed, 2627 different pages > 2.612 s/loop, 0.684 ms/page, 46765.812 MiB/s 2628 succeed, 1189 failed, 2628 different pages > 2.683 s/loop, 0.703 ms/page, 45520.990 MiB/s 2630 succeed, 1187 failed, 2630 different pages > 2.727 s/loop, 0.714 ms/page, 44789.321 MiB/s 2631 succeed, 1186 failed, 2631 different pages > ... > ok 1 Completed > > Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> Tested and works locally :) (weird stall in data below is because it was being run in a VM that was given too much memory :P): $ sudo ./transhuge-stress -d 20 TAP version 13 1..1 transhuge-stress: allocate 251 transhuge pages, using 8041 MiB virtual memory and 7 MiB of ram # 2.317 s/loop, 9.230 ms/page, 3467.040 MiB/s 251 succeed, 0 failed, 233 different pages # 0.175 s/loop, 0.696 ms/page, 46008.352 MiB/s 251 succeed, 0 failed, 235 different pages # 0.166 s/loop, 0.661 ms/page, 48416.410 MiB/s 251 succeed, 0 failed, 232 different pages # 3.367 s/loop, 13.416 ms/page, 2385.195 MiB/s 251 succeed, 0 failed, 235 different pages # 10.092 s/loop, 40.206 ms/page, 795.906 MiB/s 251 succeed, 0 failed, 231 different pages # 0.190 s/loop, 0.757 ms/page, 42252.947 MiB/s 251 succeed, 0 failed, 230 different pages # 0.170 s/loop, 0.678 ms/page, 47177.691 MiB/s 251 succeed, 0 failed, 231 different pages # 0.259 s/loop, 1.032 ms/page, 30995.582 MiB/s 251 succeed, 0 failed, 230 different pages # 1.416 s/loop, 5.642 ms/page, 5671.301 MiB/s 251 succeed, 0 failed, 230 different pages # 0.170 s/loop, 0.677 ms/page, 47252.908 MiB/s 251 succeed, 0 failed, 229 different pages # 0.166 s/loop, 0.662 ms/page, 48339.908 MiB/s 251 succeed, 0 failed, 228 different pages # 0.165 s/loop, 0.659 ms/page, 48572.554 MiB/s 251 succeed, 0 failed, 231 different pages # 0.164 s/loop, 0.655 ms/page, 48841.927 MiB/s 251 succeed, 0 failed, 228 different pages # 0.216 s/loop, 0.861 ms/page, 37184.310 MiB/s 251 succeed, 0 failed, 189 different pages # 0.175 s/loop, 0.698 ms/page, 45864.590 MiB/s 251 succeed, 0 failed, 233 different pages ok 1 Completed # Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0 Thanks for this! Tested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> > --- > Chnage in v2: > - rename hpage_* to pmd_page_* > - Link to v1: https://lore.kernel.org/all/20260902175611.1241118-1-yeoreum.yun@arm.com/#t > > --- > tools/testing/selftests/mm/guard-regions.c | 11 ++++-- > tools/testing/selftests/mm/ksm_tests.c | 16 +++++---- > tools/testing/selftests/mm/run_vmtests.sh | 4 +-- > tools/testing/selftests/mm/transhuge-stress.c | 25 +++++++------ > tools/testing/selftests/mm/vm_util.c | 36 ++++++++++++++++--- > tools/testing/selftests/mm/vm_util.h | 9 ++--- > 6 files changed, 71 insertions(+), 30 deletions(-) > > diff --git a/tools/testing/selftests/mm/guard-regions.c b/tools/testing/selftests/mm/guard-regions.c > index 5c8ec3ca75d7..e57cc7e39e41 100644 > --- a/tools/testing/selftests/mm/guard-regions.c > +++ b/tools/testing/selftests/mm/guard-regions.c > @@ -2195,14 +2195,21 @@ TEST_F(guard_regions, pagemap_scan) > TEST_F(guard_regions, collapse) > { > const unsigned long page_size = self->page_size; > - const unsigned long size = 2 * HPAGE_SIZE; > - const unsigned long num_pages = size / page_size; > + const uint64_t hpage_size = read_pmd_pagesize(); > + unsigned long size; > + unsigned long num_pages; > char *ptr; > int i; > > if (!thp_available()) > SKIP(return, "Transparent Hugepages not available\n"); > > + if (!hpage_size) > + ksft_exit_fail_msg("reading hpage_size failed\n"); > + > + size = 2 * hpage_size; > + num_pages = size / page_size; > + > /* Need file to be correct size for tests for non-anon. */ > if (variant->backing != ANON_BACKED) > ASSERT_EQ(ftruncate(self->fd, size), 0); > diff --git a/tools/testing/selftests/mm/ksm_tests.c b/tools/testing/selftests/mm/ksm_tests.c > index 5fd7792a0d47..ef27ce467b8c 100644 > --- a/tools/testing/selftests/mm/ksm_tests.c > +++ b/tools/testing/selftests/mm/ksm_tests.c > @@ -521,19 +521,23 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot, > struct timespec start_time, end_time; > unsigned long scan_time_ns; > int pagemap_fd, n_normal_pages, n_huge_pages; > + const uint64_t hpage_size = read_pmd_pagesize(); > > if (!thp_is_enabled()) { > ksft_print_msg("Transparent Hugepages not available\n"); > return KSFT_SKIP; > } > > + if (!hpage_size) > + ksft_exit_fail_msg("reading hpage_size failed\n"); > + > map_size *= MB; > size_t len = map_size; > > - len -= len % HPAGE_SIZE; > - map_ptr_orig = mmap(NULL, len + HPAGE_SIZE, PROT_READ | PROT_WRITE, > + len -= len % hpage_size; > + map_ptr_orig = mmap(NULL, len + hpage_size, PROT_READ | PROT_WRITE, > MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE, -1, 0); > - map_ptr = map_ptr_orig + HPAGE_SIZE - (uintptr_t)map_ptr_orig % HPAGE_SIZE; > + map_ptr = map_ptr_orig + hpage_size - (uintptr_t)map_ptr_orig % hpage_size; > > if (map_ptr_orig == MAP_FAILED) > err(2, "initial mmap"); > @@ -547,7 +551,7 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot, > > n_normal_pages = 0; > n_huge_pages = 0; > - for (void *p = map_ptr; p < map_ptr + len; p += HPAGE_SIZE) { > + for (void *p = map_ptr; p < map_ptr + len; p += hpage_size) { > if (allocate_transhuge(p, pagemap_fd) < 0) > n_normal_pages++; > else > @@ -578,11 +582,11 @@ static int ksm_merge_hugepages_time(int merge_type, int mapping, int prot, > 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); > + munmap(map_ptr_orig, len + hpage_size); > return KSFT_PASS; > > err_out: > - munmap(map_ptr_orig, len + HPAGE_SIZE); > + munmap(map_ptr_orig, len + hpage_size); > return KSFT_FAIL; > } > > diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh > index d09f9f6a384e..24aa1de27c25 100755 > --- a/tools/testing/selftests/mm/run_vmtests.sh > +++ b/tools/testing/selftests/mm/run_vmtests.sh > @@ -360,8 +360,8 @@ fi > CATEGORY="memfd_secret" run_test ./memfd_secret > fi > > -# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100 > -CATEGORY="ksm" run_test ./ksm_tests -H -s 100 > +# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 512 > +CATEGORY="ksm" run_test ./ksm_tests -H -s 512 > # 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 > diff --git a/tools/testing/selftests/mm/transhuge-stress.c b/tools/testing/selftests/mm/transhuge-stress.c > index 8eb0c5630e7e..9cd9790224db 100644 > --- a/tools/testing/selftests/mm/transhuge-stress.c > +++ b/tools/testing/selftests/mm/transhuge-stress.c > @@ -35,12 +35,17 @@ int main(int argc, char **argv) > size_t map_len; > int pagemap_fd; > int duration = 0; > + const uint64_t hpage_size = read_pmd_pagesize(); > + const uint64_t hpage_shift = pmd_page_shift(); > > ksft_print_header(); > > if (!thp_is_enabled()) > ksft_exit_skip("Transparent Hugepages not available\n"); > > + if (!hpage_size || !hpage_shift) > + ksft_exit_fail_msg("reading hpage_size failed\n"); > + > ram = sysconf(_SC_PHYS_PAGES); > if (ram > SIZE_MAX / psize() / 4) > ram = SIZE_MAX / 4; > @@ -70,23 +75,23 @@ int main(int argc, char **argv) > } > > warnx("allocate %zd transhuge pages, using %zd MiB virtual memory" > - " and %zd MiB of ram", len >> HPAGE_SHIFT, len >> 20, > - ram >> (20 + HPAGE_SHIFT - pshift() - 1)); > + " and %zd MiB of ram", len >> hpage_shift, len >> 20, > + ram >> (20 + hpage_shift - pshift() - 1)); > > pagemap_fd = open("/proc/self/pagemap", O_RDONLY); > if (pagemap_fd < 0) > ksft_exit_fail_msg("open pagemap\n"); > > - len -= len % HPAGE_SIZE; > - ptr = mmap(NULL, len + HPAGE_SIZE, PROT_RW, mmap_flags, backing_fd, 0); > + len -= len % hpage_size; > + ptr = mmap(NULL, len + hpage_size, PROT_RW, mmap_flags, backing_fd, 0); > if (ptr == MAP_FAILED) > ksft_exit_fail_msg("initial mmap"); > - ptr += HPAGE_SIZE - (uintptr_t)ptr % HPAGE_SIZE; > + ptr += hpage_size - (uintptr_t)ptr % hpage_size; > > if (madvise(ptr, len, MADV_HUGEPAGE)) > ksft_exit_fail_msg("MADV_HUGEPAGE"); > > - map_len = ram >> (HPAGE_SHIFT - 1); > + map_len = ram >> (hpage_shift - 1); > map = malloc(map_len); > if (!map) > ksft_exit_fail_msg("map malloc\n"); > @@ -99,7 +104,7 @@ int main(int argc, char **argv) > memset(map, 0, map_len); > > clock_gettime(CLOCK_MONOTONIC, &a); > - for (p = ptr; p < ptr + len; p += HPAGE_SIZE) { > + for (p = ptr; p < ptr + len; p += hpage_size) { > int64_t pfn; > > pfn = allocate_transhuge(p, pagemap_fd); > @@ -107,7 +112,7 @@ int main(int argc, char **argv) > if (pfn < 0) { > nr_failed++; > } else { > - size_t idx = pfn >> (HPAGE_SHIFT - pshift()); > + size_t idx = pfn >> (hpage_shift - pshift()); > > nr_succeed++; > if (idx >= map_len) { > @@ -123,7 +128,7 @@ int main(int argc, char **argv) > } > > /* split transhuge page, keep last page */ > - if (madvise(p, HPAGE_SIZE - psize(), MADV_DONTNEED)) > + if (madvise(p, hpage_size - psize(), MADV_DONTNEED)) > ksft_exit_fail_msg("MADV_DONTNEED"); > } > clock_gettime(CLOCK_MONOTONIC, &b); > @@ -131,7 +136,7 @@ int main(int argc, char **argv) > > ksft_print_msg("%.3f s/loop, %.3f ms/page, %10.3f MiB/s\t" > "%4d succeed, %4d failed, %4d different pages\n", > - s, s * 1000 / (len >> HPAGE_SHIFT), len / s / (1 << 20), > + s, s * 1000 / (len >> hpage_shift), len / s / (1 << 20), > nr_succeed, nr_failed, nr_pages); > > if (duration > 0 && b.tv_sec - start.tv_sec >= duration) { > diff --git a/tools/testing/selftests/mm/vm_util.c b/tools/testing/selftests/mm/vm_util.c > index 4821a3563036..f75bf0bacd18 100644 > --- a/tools/testing/selftests/mm/vm_util.c > +++ b/tools/testing/selftests/mm/vm_util.c > @@ -21,6 +21,8 @@ > > unsigned int __page_size; > unsigned int __page_shift; > +uint64_t __pmd_page_size; > +uint64_t __pmd_page_shift; > > uint64_t pagemap_get_entry(int fd, char *start) > { > @@ -161,6 +163,9 @@ uint64_t read_pmd_pagesize(void) > char buf[20]; > ssize_t num_read; > > + if (__pmd_page_size) > + return __pmd_page_size; > + > fd = open(PMD_SIZE_FILE_PATH, O_RDONLY); > if (fd == -1) > return 0; > @@ -173,7 +178,25 @@ uint64_t read_pmd_pagesize(void) > buf[num_read] = '\0'; > close(fd); > > - return strtoul(buf, NULL, 10); > + __pmd_page_size = strtoul(buf, NULL, 10); > + > + return __pmd_page_size; > +} > + > +uint64_t pmd_page_shift(void) > +{ > + if (__pmd_page_shift) > + return __pmd_page_shift; > + > + if (!__pmd_page_size) > + __pmd_page_size = read_pmd_pagesize(); > + > + if (!__pmd_page_size) > + return 0; > + > + __pmd_page_shift = (ffsl(__pmd_page_size) - 1); > + > + return __pmd_page_shift; > } > > unsigned long rss_anon(void) > @@ -452,14 +475,19 @@ bool check_huge_shmem(void *addr, size_t len, int nr_hpages, uint64_t hpage_size > int64_t allocate_transhuge(void *ptr, int pagemap_fd) > { > uint64_t ent[2]; > + const uint64_t hpage_size = read_pmd_pagesize(); > + const uint64_t hpage_shift = pmd_page_shift(); > + > + if (!hpage_size || !hpage_shift) > + return -1; > > /* drop pmd */ > - if (mmap(ptr, HPAGE_SIZE, PROT_READ | PROT_WRITE, > + if (mmap(ptr, hpage_size, PROT_READ | PROT_WRITE, > MAP_FIXED | MAP_ANONYMOUS | > MAP_NORESERVE | MAP_PRIVATE, -1, 0) != ptr) > ksft_exit_fail_msg("mmap transhuge\n"); > > - if (madvise(ptr, HPAGE_SIZE, MADV_HUGEPAGE)) > + if (madvise(ptr, hpage_size, MADV_HUGEPAGE)) > ksft_exit_fail_msg("MADV_HUGEPAGE\n"); > > /* allocate transparent huge page */ > @@ -471,7 +499,7 @@ int64_t allocate_transhuge(void *ptr, int pagemap_fd) > > if (PAGEMAP_PRESENT(ent[0]) && PAGEMAP_PRESENT(ent[1]) && > PAGEMAP_PFN(ent[0]) + 1 == PAGEMAP_PFN(ent[1]) && > - !(PAGEMAP_PFN(ent[0]) & ((1 << (HPAGE_SHIFT - pshift())) - 1))) > + !(PAGEMAP_PFN(ent[0]) & ((1 << (hpage_shift - pshift())) - 1))) > return PAGEMAP_PFN(ent[0]); > > return -1; > diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h > index 9a49af88702e..1d2608c1ad08 100644 > --- a/tools/testing/selftests/mm/vm_util.h > +++ b/tools/testing/selftests/mm/vm_util.h > @@ -31,6 +31,8 @@ > > extern unsigned int __page_size; > extern unsigned int __page_shift; > +extern uint64_t __pmd_page_size; > +extern uint64_t __pmd_page_shift; > > /* > * Represents an open fd and PROCMAP_QUERY state for binary (via ioctl) > @@ -89,6 +91,7 @@ unsigned long pagemap_get_pfn(int fd, char *start); > void clear_softdirty(void); > bool check_for_pattern(FILE *fp, const char *pattern, char *buf, size_t len); > uint64_t read_pmd_pagesize(void); > +uint64_t pmd_page_shift(void); > unsigned long rss_anon(void); > bool check_huge_anon(void *addr, size_t len, int nr_hpages, uint64_t hpage_size); > bool check_huge_file(void *addr, size_t len, int nr_hpages, uint64_t hpage_size); > @@ -157,12 +160,6 @@ int ksm_stop(void); > int get_hardware_corrupted_size(unsigned long *val); > int unpoison_memory(unsigned long pfn); > > -/* > - * On ppc64 this will only work with radix 2M hugepage size > - */ > -#define HPAGE_SHIFT 21 > -#define HPAGE_SIZE (1 << HPAGE_SHIFT) > - > #define PAGEMAP_PRESENT(ent) (((ent) & (1ull << 63)) != 0) > #define PAGEMAP_PFN(ent) ((ent) & ((1ull << 55) - 1)) > > -- > LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7} > -- Cheers, Lorenzo ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro 2026-09-07 8:15 [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro Yeoreum Yun 2026-09-07 11:40 ` Sarthak Sharma 2026-09-07 12:46 ` Lorenzo Stoakes (ARM) @ 2026-09-07 14:36 ` David Hildenbrand (Arm) 2026-09-08 4:21 ` Sarthak Sharma 2026-09-08 8:23 ` Yeoreum Yun 2 siblings, 2 replies; 8+ messages in thread From: David Hildenbrand (Arm) @ 2026-09-07 14:36 UTC (permalink / raw) To: Yeoreum Yun, linux-mm, linux-kselftest Cc: akpm, ljs, liam, vbabka, rppt, surenb, mhocko, shuah, ziy, baolin.wang, nico.pache, ryan.roberts, dev.jain, baohua, lance.yang, usama.arif, kas, sarthak.sharma On 9/7/26 10:15, Yeoreum Yun wrote: > HPAGE_SIZE and HPAGE_SHIFT macro is written based on the 4KB PAGE_SIZE. > When this macro is used in some test, test result would be strange in > the system where PAGE_SIZE is more then 4KB. > > Here is the example with transhuge-stress test with 16KB PAGE_SIZE: > > transhuge-stress: allocate 61073 transhuge pages, using 122146 MiB virtual memory and 1908 MiB of ram > 3.292 s/loop, 0.054 ms/page, 37106.002 MiB/s 2566 succeed, 58507 failed, 2566 different pages > 0.591 s/loop, 0.010 ms/page, 206850.792 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.527 s/loop, 0.009 ms/page, 231895.107 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.527 s/loop, 0.009 ms/page, 231839.704 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.528 s/loop, 0.009 ms/page, 231544.782 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.528 s/loop, 0.009 ms/page, 231462.074 MiB/s 0 succeed, 61073 failed, 0 different pages > 0.527 s/loop, 0.009 ms/page, 231770.300 MiB/s 0 succeed, 61073 failed, 0 different pages > ... > ok 1 Completed > > Remove the HPAGE_SIZE and HPAGE_SHIFT macros and introduce pmd_page_shift() > helper to get the HPAGE_SHIFT properly. For HPAGE_SIZE, use pre-existing > helper, read_pmd_pagesize(). > > Also, run the KSM_MERGE_TIME_HUGE_PAGES test with a size of 512 MiB, > which is the least common multiple of the PMD sizes for 4 KiB, 16 KiB, > and 64 KiB base pages. Since allocate_transhuge() allocates mappings in > PMD-sized units, the test may fail with the previous size of 100 MiB, > which is not a multiple of the PMD size when the base page size is > 16 KiB or 64 KiB. > > After this patch, output of transhuge-stress: > > transhuge-stress: allocate 3817 transhuge pages, using 122146 MiB virtual memory and 119 MiB of ram > 2.558 s/loop, 0.670 ms/page, 47755.759 MiB/s 2585 succeed, 1232 failed, 2585 different pages > 2.640 s/loop, 0.692 ms/page, 46268.432 MiB/s 2585 succeed, 1232 failed, 2585 different pages > 2.635 s/loop, 0.690 ms/page, 46360.298 MiB/s 2585 succeed, 1232 failed, 2585 different pages > 2.782 s/loop, 0.729 ms/page, 43899.795 MiB/s 2616 succeed, 1201 failed, 2616 different pages > 2.692 s/loop, 0.705 ms/page, 45380.876 MiB/s 2627 succeed, 1190 failed, 2627 different pages > 2.612 s/loop, 0.684 ms/page, 46765.812 MiB/s 2628 succeed, 1189 failed, 2628 different pages > 2.683 s/loop, 0.703 ms/page, 45520.990 MiB/s 2630 succeed, 1187 failed, 2630 different pages > 2.727 s/loop, 0.714 ms/page, 44789.321 MiB/s 2631 succeed, 1186 failed, 2631 different pages > ... > ok 1 Completed > > Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > --- [...] > diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh > index d09f9f6a384e..24aa1de27c25 100755 > --- a/tools/testing/selftests/mm/run_vmtests.sh > +++ b/tools/testing/selftests/mm/run_vmtests.sh > @@ -360,8 +360,8 @@ fi > CATEGORY="memfd_secret" run_test ./memfd_secret > fi > > -# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100 > -CATEGORY="ksm" run_test ./ksm_tests -H -s 100 > +# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 512 > +CATEGORY="ksm" run_test ./ksm_tests -H -s 512 Why the magic value 512? (desrves a comment) A clear sign that the ksm tests must be rewritten to be standalone and just handle this internally. @Sarthak > # 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 [...] > index 4821a3563036..f75bf0bacd18 100644 > --- a/tools/testing/selftests/mm/vm_util.c > +++ b/tools/testing/selftests/mm/vm_util.c > @@ -21,6 +21,8 @@ > > unsigned int __page_size; > unsigned int __page_shift; > +uint64_t __pmd_page_size; > +uint64_t __pmd_page_shift; > > uint64_t pagemap_get_entry(int fd, char *start) > { > @@ -161,6 +163,9 @@ uint64_t read_pmd_pagesize(void) > char buf[20]; > ssize_t num_read; > > + if (__pmd_page_size) > + return __pmd_page_size; > + > fd = open(PMD_SIZE_FILE_PATH, O_RDONLY); > if (fd == -1) > return 0; > @@ -173,7 +178,25 @@ uint64_t read_pmd_pagesize(void) > buf[num_read] = '\0'; > close(fd); > > - return strtoul(buf, NULL, 10); > + __pmd_page_size = strtoul(buf, NULL, 10); > + > + return __pmd_page_size; > +} > + > +uint64_t pmd_page_shift(void) > +{ > + if (__pmd_page_shift) > + return __pmd_page_shift; > + > + if (!__pmd_page_size) > + __pmd_page_size = read_pmd_pagesize(); > + > + if (!__pmd_page_size) > + return 0; > + > + __pmd_page_shift = (ffsl(__pmd_page_size) - 1); > + > + return __pmd_page_shift; > } The interface is a bit inconsistent. read_pmd_pagesize() vs. pmd_page_shift(). Consider renaming read_pmd_pagesize() to pmd_pagesize() in a cleanup patch. ... or (better?) adding a size_to_shift() helper instead? I think most places that want the shift also want the size. So this can just be const uint64_t hpage_size = read_pmd_pagesize(); const uint64_t hpage_shift = size_to_shift(hpage_size); In size_to_shift(), you can just handle if (size == 0) return 0; etc. -- Cheers, David ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro 2026-09-07 14:36 ` David Hildenbrand (Arm) @ 2026-09-08 4:21 ` Sarthak Sharma 2026-09-08 8:23 ` Yeoreum Yun 1 sibling, 0 replies; 8+ messages in thread From: Sarthak Sharma @ 2026-09-08 4:21 UTC (permalink / raw) To: David Hildenbrand (Arm), Yeoreum Yun, linux-mm, linux-kselftest Cc: akpm, ljs, liam, vbabka, rppt, surenb, mhocko, shuah, ziy, baolin.wang, nico.pache, ryan.roberts, dev.jain, baohua, lance.yang, usama.arif, kas On 9/7/26 8:06 PM, David Hildenbrand (Arm) wrote: > On 9/7/26 10:15, Yeoreum Yun wrote: >> HPAGE_SIZE and HPAGE_SHIFT macro is written based on the 4KB PAGE_SIZE. >> When this macro is used in some test, test result would be strange in >> the system where PAGE_SIZE is more then 4KB. >> >> Here is the example with transhuge-stress test with 16KB PAGE_SIZE: >> >> transhuge-stress: allocate 61073 transhuge pages, using 122146 MiB virtual memory and 1908 MiB of ram >> 3.292 s/loop, 0.054 ms/page, 37106.002 MiB/s 2566 succeed, 58507 failed, 2566 different pages >> 0.591 s/loop, 0.010 ms/page, 206850.792 MiB/s 0 succeed, 61073 failed, 0 different pages >> 0.527 s/loop, 0.009 ms/page, 231895.107 MiB/s 0 succeed, 61073 failed, 0 different pages >> 0.527 s/loop, 0.009 ms/page, 231839.704 MiB/s 0 succeed, 61073 failed, 0 different pages >> 0.528 s/loop, 0.009 ms/page, 231544.782 MiB/s 0 succeed, 61073 failed, 0 different pages >> 0.528 s/loop, 0.009 ms/page, 231462.074 MiB/s 0 succeed, 61073 failed, 0 different pages >> 0.527 s/loop, 0.009 ms/page, 231770.300 MiB/s 0 succeed, 61073 failed, 0 different pages >> ... >> ok 1 Completed >> >> Remove the HPAGE_SIZE and HPAGE_SHIFT macros and introduce pmd_page_shift() >> helper to get the HPAGE_SHIFT properly. For HPAGE_SIZE, use pre-existing >> helper, read_pmd_pagesize(). >> >> Also, run the KSM_MERGE_TIME_HUGE_PAGES test with a size of 512 MiB, >> which is the least common multiple of the PMD sizes for 4 KiB, 16 KiB, >> and 64 KiB base pages. Since allocate_transhuge() allocates mappings in >> PMD-sized units, the test may fail with the previous size of 100 MiB, >> which is not a multiple of the PMD size when the base page size is >> 16 KiB or 64 KiB. >> >> After this patch, output of transhuge-stress: >> >> transhuge-stress: allocate 3817 transhuge pages, using 122146 MiB virtual memory and 119 MiB of ram >> 2.558 s/loop, 0.670 ms/page, 47755.759 MiB/s 2585 succeed, 1232 failed, 2585 different pages >> 2.640 s/loop, 0.692 ms/page, 46268.432 MiB/s 2585 succeed, 1232 failed, 2585 different pages >> 2.635 s/loop, 0.690 ms/page, 46360.298 MiB/s 2585 succeed, 1232 failed, 2585 different pages >> 2.782 s/loop, 0.729 ms/page, 43899.795 MiB/s 2616 succeed, 1201 failed, 2616 different pages >> 2.692 s/loop, 0.705 ms/page, 45380.876 MiB/s 2627 succeed, 1190 failed, 2627 different pages >> 2.612 s/loop, 0.684 ms/page, 46765.812 MiB/s 2628 succeed, 1189 failed, 2628 different pages >> 2.683 s/loop, 0.703 ms/page, 45520.990 MiB/s 2630 succeed, 1187 failed, 2630 different pages >> 2.727 s/loop, 0.714 ms/page, 44789.321 MiB/s 2631 succeed, 1186 failed, 2631 different pages >> ... >> ok 1 Completed >> >> Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> >> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> >> --- > > > [...] > >> diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh >> index d09f9f6a384e..24aa1de27c25 100755 >> --- a/tools/testing/selftests/mm/run_vmtests.sh >> +++ b/tools/testing/selftests/mm/run_vmtests.sh >> @@ -360,8 +360,8 @@ fi >> CATEGORY="memfd_secret" run_test ./memfd_secret >> fi >> >> -# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100 >> -CATEGORY="ksm" run_test ./ksm_tests -H -s 100 >> +# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 512 >> +CATEGORY="ksm" run_test ./ksm_tests -H -s 512 > > > Why the magic value 512? (desrves a comment) > > A clear sign that the ksm tests must be rewritten to be standalone and just > handle this internally. @Sarthak Sure David, I'll work on this. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro 2026-09-07 14:36 ` David Hildenbrand (Arm) 2026-09-08 4:21 ` Sarthak Sharma @ 2026-09-08 8:23 ` Yeoreum Yun 2026-09-08 10:21 ` David Hildenbrand (Arm) 1 sibling, 1 reply; 8+ messages in thread From: Yeoreum Yun @ 2026-09-08 8:23 UTC (permalink / raw) To: David Hildenbrand (Arm) Cc: Yeoreum Yun, linux-mm, linux-kselftest, akpm, ljs, liam, vbabka, rppt, surenb, mhocko, shuah, ziy, baolin.wang, nico.pache, ryan.roberts, dev.jain, baohua, lance.yang, usama.arif, kas, sarthak.sharma On Mon, Sep 07, 2026 at 04:36:56PM +0200, David Hildenbrand (Arm) wrote: > On 9/7/26 10:15, Yeoreum Yun wrote: > > HPAGE_SIZE and HPAGE_SHIFT macro is written based on the 4KB PAGE_SIZE. > > When this macro is used in some test, test result would be strange in > > the system where PAGE_SIZE is more then 4KB. > > > > Here is the example with transhuge-stress test with 16KB PAGE_SIZE: > > > > transhuge-stress: allocate 61073 transhuge pages, using 122146 MiB virtual memory and 1908 MiB of ram > > 3.292 s/loop, 0.054 ms/page, 37106.002 MiB/s 2566 succeed, 58507 failed, 2566 different pages > > 0.591 s/loop, 0.010 ms/page, 206850.792 MiB/s 0 succeed, 61073 failed, 0 different pages > > 0.527 s/loop, 0.009 ms/page, 231895.107 MiB/s 0 succeed, 61073 failed, 0 different pages > > 0.527 s/loop, 0.009 ms/page, 231839.704 MiB/s 0 succeed, 61073 failed, 0 different pages > > 0.528 s/loop, 0.009 ms/page, 231544.782 MiB/s 0 succeed, 61073 failed, 0 different pages > > 0.528 s/loop, 0.009 ms/page, 231462.074 MiB/s 0 succeed, 61073 failed, 0 different pages > > 0.527 s/loop, 0.009 ms/page, 231770.300 MiB/s 0 succeed, 61073 failed, 0 different pages > > ... > > ok 1 Completed > > > > Remove the HPAGE_SIZE and HPAGE_SHIFT macros and introduce pmd_page_shift() > > helper to get the HPAGE_SHIFT properly. For HPAGE_SIZE, use pre-existing > > helper, read_pmd_pagesize(). > > > > Also, run the KSM_MERGE_TIME_HUGE_PAGES test with a size of 512 MiB, > > which is the least common multiple of the PMD sizes for 4 KiB, 16 KiB, > > and 64 KiB base pages. Since allocate_transhuge() allocates mappings in > > PMD-sized units, the test may fail with the previous size of 100 MiB, > > which is not a multiple of the PMD size when the base page size is > > 16 KiB or 64 KiB. > > > > After this patch, output of transhuge-stress: > > > > transhuge-stress: allocate 3817 transhuge pages, using 122146 MiB virtual memory and 119 MiB of ram > > 2.558 s/loop, 0.670 ms/page, 47755.759 MiB/s 2585 succeed, 1232 failed, 2585 different pages > > 2.640 s/loop, 0.692 ms/page, 46268.432 MiB/s 2585 succeed, 1232 failed, 2585 different pages > > 2.635 s/loop, 0.690 ms/page, 46360.298 MiB/s 2585 succeed, 1232 failed, 2585 different pages > > 2.782 s/loop, 0.729 ms/page, 43899.795 MiB/s 2616 succeed, 1201 failed, 2616 different pages > > 2.692 s/loop, 0.705 ms/page, 45380.876 MiB/s 2627 succeed, 1190 failed, 2627 different pages > > 2.612 s/loop, 0.684 ms/page, 46765.812 MiB/s 2628 succeed, 1189 failed, 2628 different pages > > 2.683 s/loop, 0.703 ms/page, 45520.990 MiB/s 2630 succeed, 1187 failed, 2630 different pages > > 2.727 s/loop, 0.714 ms/page, 44789.321 MiB/s 2631 succeed, 1186 failed, 2631 different pages > > ... > > ok 1 Completed > > > > Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > > --- > > > [...] > > > diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh > > index d09f9f6a384e..24aa1de27c25 100755 > > --- a/tools/testing/selftests/mm/run_vmtests.sh > > +++ b/tools/testing/selftests/mm/run_vmtests.sh > > @@ -360,8 +360,8 @@ fi > > CATEGORY="memfd_secret" run_test ./memfd_secret > > fi > > > > -# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100 > > -CATEGORY="ksm" run_test ./ksm_tests -H -s 100 > > +# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 512 > > +CATEGORY="ksm" run_test ./ksm_tests -H -s 512 > > > Why the magic value 512? (desrves a comment) > > A clear sign that the ksm tests must be rewritten to be standalone and just > handle this internally. @Sarthak Acked. I thought it's enough to spell out in commit message but I'll spell out into comment too in this round not refactorying by me for ksm test. > > > # 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 > > [...] > > > index 4821a3563036..f75bf0bacd18 100644 > > --- a/tools/testing/selftests/mm/vm_util.c > > +++ b/tools/testing/selftests/mm/vm_util.c > > @@ -21,6 +21,8 @@ > > > > unsigned int __page_size; > > unsigned int __page_shift; > > +uint64_t __pmd_page_size; > > +uint64_t __pmd_page_shift; > > > > uint64_t pagemap_get_entry(int fd, char *start) > > { > > @@ -161,6 +163,9 @@ uint64_t read_pmd_pagesize(void) > > char buf[20]; > > ssize_t num_read; > > > > + if (__pmd_page_size) > > + return __pmd_page_size; > > + > > fd = open(PMD_SIZE_FILE_PATH, O_RDONLY); > > if (fd == -1) > > return 0; > > @@ -173,7 +178,25 @@ uint64_t read_pmd_pagesize(void) > > buf[num_read] = '\0'; > > close(fd); > > > > - return strtoul(buf, NULL, 10); > > + __pmd_page_size = strtoul(buf, NULL, 10); > > + > > + return __pmd_page_size; > > +} > > + > > +uint64_t pmd_page_shift(void) > > +{ > > + if (__pmd_page_shift) > > + return __pmd_page_shift; > > + > > + if (!__pmd_page_size) > > + __pmd_page_size = read_pmd_pagesize(); > > + > > + if (!__pmd_page_size) > > + return 0; > > + > > + __pmd_page_shift = (ffsl(__pmd_page_size) - 1); > > + > > + return __pmd_page_shift; > > } > The interface is a bit inconsistent. > > read_pmd_pagesize() vs. pmd_page_shift(). > > Consider renaming read_pmd_pagesize() to pmd_pagesize() in a cleanup patch. Okay. > ... or (better?) adding a size_to_shift() helper instead? > > I think most places that want the shift also want the size. > > So this can just be > > const uint64_t hpage_size = read_pmd_pagesize(); > const uint64_t hpage_shift = size_to_shift(hpage_size); > > > In size_to_shift(), you can just handle > > if (size == 0) > return 0; Hmm, most of tests care mainly two sizes and shiftes -- psize()/pshift() and pmd_pagesize() and pmd_pageshift(). Would it be better to keep both kinda of helpers and add size_to_shift() helper for nother hpage size then? -- Sincerely, Yeoreum Yun ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro 2026-09-08 8:23 ` Yeoreum Yun @ 2026-09-08 10:21 ` David Hildenbrand (Arm) 2026-09-09 16:40 ` Yeoreum Yun 0 siblings, 1 reply; 8+ messages in thread From: David Hildenbrand (Arm) @ 2026-09-08 10:21 UTC (permalink / raw) To: Yeoreum Yun Cc: linux-mm, linux-kselftest, akpm, ljs, liam, vbabka, rppt, surenb, mhocko, shuah, ziy, baolin.wang, nico.pache, ryan.roberts, dev.jain, baohua, lance.yang, usama.arif, kas, sarthak.sharma On 9/8/26 10:23, Yeoreum Yun wrote: > On Mon, Sep 07, 2026 at 04:36:56PM +0200, David Hildenbrand (Arm) wrote: >> On 9/7/26 10:15, Yeoreum Yun wrote: >>> HPAGE_SIZE and HPAGE_SHIFT macro is written based on the 4KB PAGE_SIZE. >>> When this macro is used in some test, test result would be strange in >>> the system where PAGE_SIZE is more then 4KB. >>> >>> Here is the example with transhuge-stress test with 16KB PAGE_SIZE: >>> >>> transhuge-stress: allocate 61073 transhuge pages, using 122146 MiB virtual memory and 1908 MiB of ram >>> 3.292 s/loop, 0.054 ms/page, 37106.002 MiB/s 2566 succeed, 58507 failed, 2566 different pages >>> 0.591 s/loop, 0.010 ms/page, 206850.792 MiB/s 0 succeed, 61073 failed, 0 different pages >>> 0.527 s/loop, 0.009 ms/page, 231895.107 MiB/s 0 succeed, 61073 failed, 0 different pages >>> 0.527 s/loop, 0.009 ms/page, 231839.704 MiB/s 0 succeed, 61073 failed, 0 different pages >>> 0.528 s/loop, 0.009 ms/page, 231544.782 MiB/s 0 succeed, 61073 failed, 0 different pages >>> 0.528 s/loop, 0.009 ms/page, 231462.074 MiB/s 0 succeed, 61073 failed, 0 different pages >>> 0.527 s/loop, 0.009 ms/page, 231770.300 MiB/s 0 succeed, 61073 failed, 0 different pages >>> ... >>> ok 1 Completed >>> >>> Remove the HPAGE_SIZE and HPAGE_SHIFT macros and introduce pmd_page_shift() >>> helper to get the HPAGE_SHIFT properly. For HPAGE_SIZE, use pre-existing >>> helper, read_pmd_pagesize(). >>> >>> Also, run the KSM_MERGE_TIME_HUGE_PAGES test with a size of 512 MiB, >>> which is the least common multiple of the PMD sizes for 4 KiB, 16 KiB, >>> and 64 KiB base pages. Since allocate_transhuge() allocates mappings in >>> PMD-sized units, the test may fail with the previous size of 100 MiB, >>> which is not a multiple of the PMD size when the base page size is >>> 16 KiB or 64 KiB. >>> >>> After this patch, output of transhuge-stress: >>> >>> transhuge-stress: allocate 3817 transhuge pages, using 122146 MiB virtual memory and 119 MiB of ram >>> 2.558 s/loop, 0.670 ms/page, 47755.759 MiB/s 2585 succeed, 1232 failed, 2585 different pages >>> 2.640 s/loop, 0.692 ms/page, 46268.432 MiB/s 2585 succeed, 1232 failed, 2585 different pages >>> 2.635 s/loop, 0.690 ms/page, 46360.298 MiB/s 2585 succeed, 1232 failed, 2585 different pages >>> 2.782 s/loop, 0.729 ms/page, 43899.795 MiB/s 2616 succeed, 1201 failed, 2616 different pages >>> 2.692 s/loop, 0.705 ms/page, 45380.876 MiB/s 2627 succeed, 1190 failed, 2627 different pages >>> 2.612 s/loop, 0.684 ms/page, 46765.812 MiB/s 2628 succeed, 1189 failed, 2628 different pages >>> 2.683 s/loop, 0.703 ms/page, 45520.990 MiB/s 2630 succeed, 1187 failed, 2630 different pages >>> 2.727 s/loop, 0.714 ms/page, 44789.321 MiB/s 2631 succeed, 1186 failed, 2631 different pages >>> ... >>> ok 1 Completed >>> >>> Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> >>> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> >>> --- >> >> >> [...] >> >>> diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh >>> index d09f9f6a384e..24aa1de27c25 100755 >>> --- a/tools/testing/selftests/mm/run_vmtests.sh >>> +++ b/tools/testing/selftests/mm/run_vmtests.sh >>> @@ -360,8 +360,8 @@ fi >>> CATEGORY="memfd_secret" run_test ./memfd_secret >>> fi >>> >>> -# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100 >>> -CATEGORY="ksm" run_test ./ksm_tests -H -s 100 >>> +# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 512 >>> +CATEGORY="ksm" run_test ./ksm_tests -H -s 512 >> >> >> Why the magic value 512? (desrves a comment) >> >> A clear sign that the ksm tests must be rewritten to be standalone and just >> handle this internally. @Sarthak > > Acked. I thought it's enough to spell out in commit message but > I'll spell out into comment too in this round not refactorying by me > for ksm test. > >> >>> # 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 >> >> [...] >> >>> index 4821a3563036..f75bf0bacd18 100644 >>> --- a/tools/testing/selftests/mm/vm_util.c >>> +++ b/tools/testing/selftests/mm/vm_util.c >>> @@ -21,6 +21,8 @@ >>> >>> unsigned int __page_size; >>> unsigned int __page_shift; >>> +uint64_t __pmd_page_size; >>> +uint64_t __pmd_page_shift; >>> >>> uint64_t pagemap_get_entry(int fd, char *start) >>> { >>> @@ -161,6 +163,9 @@ uint64_t read_pmd_pagesize(void) >>> char buf[20]; >>> ssize_t num_read; >>> >>> + if (__pmd_page_size) >>> + return __pmd_page_size; >>> + >>> fd = open(PMD_SIZE_FILE_PATH, O_RDONLY); >>> if (fd == -1) >>> return 0; >>> @@ -173,7 +178,25 @@ uint64_t read_pmd_pagesize(void) >>> buf[num_read] = '\0'; >>> close(fd); >>> >>> - return strtoul(buf, NULL, 10); >>> + __pmd_page_size = strtoul(buf, NULL, 10); >>> + >>> + return __pmd_page_size; >>> +} >>> + >>> +uint64_t pmd_page_shift(void) >>> +{ >>> + if (__pmd_page_shift) >>> + return __pmd_page_shift; >>> + >>> + if (!__pmd_page_size) >>> + __pmd_page_size = read_pmd_pagesize(); >>> + >>> + if (!__pmd_page_size) >>> + return 0; >>> + >>> + __pmd_page_shift = (ffsl(__pmd_page_size) - 1); >>> + >>> + return __pmd_page_shift; >>> } >> The interface is a bit inconsistent. >> >> read_pmd_pagesize() vs. pmd_page_shift(). >> >> Consider renaming read_pmd_pagesize() to pmd_pagesize() in a cleanup patch. > > Okay. > >> ... or (better?) adding a size_to_shift() helper instead? >> >> I think most places that want the shift also want the size. >> >> So this can just be >> >> const uint64_t hpage_size = read_pmd_pagesize(); >> const uint64_t hpage_shift = size_to_shift(hpage_size); >> >> >> In size_to_shift(), you can just handle >> >> if (size == 0) >> return 0; > > Hmm, most of tests care mainly two sizes and shiftes -- > psize()/pshift() and pmd_pagesize() and pmd_pageshift(). > > Would it be better to keep both kinda of helpers and > add size_to_shift() helper for nother hpage size then? Works for me as well. As long as it's consistent. Maybe even pmd_psize() and pmd_pshift() to match our custom psize() and pshift()? -- Cheers, David ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro 2026-09-08 10:21 ` David Hildenbrand (Arm) @ 2026-09-09 16:40 ` Yeoreum Yun 0 siblings, 0 replies; 8+ messages in thread From: Yeoreum Yun @ 2026-09-09 16:40 UTC (permalink / raw) To: David Hildenbrand (Arm) Cc: Yeoreum Yun, linux-mm, linux-kselftest, akpm, ljs, liam, vbabka, rppt, surenb, mhocko, shuah, ziy, baolin.wang, nico.pache, ryan.roberts, dev.jain, baohua, lance.yang, usama.arif, kas, sarthak.sharma On Tue, Sep 08, 2026 at 12:21:31PM +0200, David Hildenbrand (Arm) wrote: > On 9/8/26 10:23, Yeoreum Yun wrote: > > On Mon, Sep 07, 2026 at 04:36:56PM +0200, David Hildenbrand (Arm) wrote: > >> On 9/7/26 10:15, Yeoreum Yun wrote: > >>> HPAGE_SIZE and HPAGE_SHIFT macro is written based on the 4KB PAGE_SIZE. > >>> When this macro is used in some test, test result would be strange in > >>> the system where PAGE_SIZE is more then 4KB. > >>> > >>> Here is the example with transhuge-stress test with 16KB PAGE_SIZE: > >>> > >>> transhuge-stress: allocate 61073 transhuge pages, using 122146 MiB virtual memory and 1908 MiB of ram > >>> 3.292 s/loop, 0.054 ms/page, 37106.002 MiB/s 2566 succeed, 58507 failed, 2566 different pages > >>> 0.591 s/loop, 0.010 ms/page, 206850.792 MiB/s 0 succeed, 61073 failed, 0 different pages > >>> 0.527 s/loop, 0.009 ms/page, 231895.107 MiB/s 0 succeed, 61073 failed, 0 different pages > >>> 0.527 s/loop, 0.009 ms/page, 231839.704 MiB/s 0 succeed, 61073 failed, 0 different pages > >>> 0.528 s/loop, 0.009 ms/page, 231544.782 MiB/s 0 succeed, 61073 failed, 0 different pages > >>> 0.528 s/loop, 0.009 ms/page, 231462.074 MiB/s 0 succeed, 61073 failed, 0 different pages > >>> 0.527 s/loop, 0.009 ms/page, 231770.300 MiB/s 0 succeed, 61073 failed, 0 different pages > >>> ... > >>> ok 1 Completed > >>> > >>> Remove the HPAGE_SIZE and HPAGE_SHIFT macros and introduce pmd_page_shift() > >>> helper to get the HPAGE_SHIFT properly. For HPAGE_SIZE, use pre-existing > >>> helper, read_pmd_pagesize(). > >>> > >>> Also, run the KSM_MERGE_TIME_HUGE_PAGES test with a size of 512 MiB, > >>> which is the least common multiple of the PMD sizes for 4 KiB, 16 KiB, > >>> and 64 KiB base pages. Since allocate_transhuge() allocates mappings in > >>> PMD-sized units, the test may fail with the previous size of 100 MiB, > >>> which is not a multiple of the PMD size when the base page size is > >>> 16 KiB or 64 KiB. > >>> > >>> After this patch, output of transhuge-stress: > >>> > >>> transhuge-stress: allocate 3817 transhuge pages, using 122146 MiB virtual memory and 119 MiB of ram > >>> 2.558 s/loop, 0.670 ms/page, 47755.759 MiB/s 2585 succeed, 1232 failed, 2585 different pages > >>> 2.640 s/loop, 0.692 ms/page, 46268.432 MiB/s 2585 succeed, 1232 failed, 2585 different pages > >>> 2.635 s/loop, 0.690 ms/page, 46360.298 MiB/s 2585 succeed, 1232 failed, 2585 different pages > >>> 2.782 s/loop, 0.729 ms/page, 43899.795 MiB/s 2616 succeed, 1201 failed, 2616 different pages > >>> 2.692 s/loop, 0.705 ms/page, 45380.876 MiB/s 2627 succeed, 1190 failed, 2627 different pages > >>> 2.612 s/loop, 0.684 ms/page, 46765.812 MiB/s 2628 succeed, 1189 failed, 2628 different pages > >>> 2.683 s/loop, 0.703 ms/page, 45520.990 MiB/s 2630 succeed, 1187 failed, 2630 different pages > >>> 2.727 s/loop, 0.714 ms/page, 44789.321 MiB/s 2631 succeed, 1186 failed, 2631 different pages > >>> ... > >>> ok 1 Completed > >>> > >>> Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> > >>> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > >>> --- > >> > >> > >> [...] > >> > >>> diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh > >>> index d09f9f6a384e..24aa1de27c25 100755 > >>> --- a/tools/testing/selftests/mm/run_vmtests.sh > >>> +++ b/tools/testing/selftests/mm/run_vmtests.sh > >>> @@ -360,8 +360,8 @@ fi > >>> CATEGORY="memfd_secret" run_test ./memfd_secret > >>> fi > >>> > >>> -# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 100 > >>> -CATEGORY="ksm" run_test ./ksm_tests -H -s 100 > >>> +# KSM KSM_MERGE_TIME_HUGE_PAGES test with size of 512 > >>> +CATEGORY="ksm" run_test ./ksm_tests -H -s 512 > >> > >> > >> Why the magic value 512? (desrves a comment) > >> > >> A clear sign that the ksm tests must be rewritten to be standalone and just > >> handle this internally. @Sarthak > > > > Acked. I thought it's enough to spell out in commit message but > > I'll spell out into comment too in this round not refactorying by me > > for ksm test. > > > >> > >>> # 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 > >> > >> [...] > >> > >>> index 4821a3563036..f75bf0bacd18 100644 > >>> --- a/tools/testing/selftests/mm/vm_util.c > >>> +++ b/tools/testing/selftests/mm/vm_util.c > >>> @@ -21,6 +21,8 @@ > >>> > >>> unsigned int __page_size; > >>> unsigned int __page_shift; > >>> +uint64_t __pmd_page_size; > >>> +uint64_t __pmd_page_shift; > >>> > >>> uint64_t pagemap_get_entry(int fd, char *start) > >>> { > >>> @@ -161,6 +163,9 @@ uint64_t read_pmd_pagesize(void) > >>> char buf[20]; > >>> ssize_t num_read; > >>> > >>> + if (__pmd_page_size) > >>> + return __pmd_page_size; > >>> + > >>> fd = open(PMD_SIZE_FILE_PATH, O_RDONLY); > >>> if (fd == -1) > >>> return 0; > >>> @@ -173,7 +178,25 @@ uint64_t read_pmd_pagesize(void) > >>> buf[num_read] = '\0'; > >>> close(fd); > >>> > >>> - return strtoul(buf, NULL, 10); > >>> + __pmd_page_size = strtoul(buf, NULL, 10); > >>> + > >>> + return __pmd_page_size; > >>> +} > >>> + > >>> +uint64_t pmd_page_shift(void) > >>> +{ > >>> + if (__pmd_page_shift) > >>> + return __pmd_page_shift; > >>> + > >>> + if (!__pmd_page_size) > >>> + __pmd_page_size = read_pmd_pagesize(); > >>> + > >>> + if (!__pmd_page_size) > >>> + return 0; > >>> + > >>> + __pmd_page_shift = (ffsl(__pmd_page_size) - 1); > >>> + > >>> + return __pmd_page_shift; > >>> } > >> The interface is a bit inconsistent. > >> > >> read_pmd_pagesize() vs. pmd_page_shift(). > >> > >> Consider renaming read_pmd_pagesize() to pmd_pagesize() in a cleanup patch. > > > > Okay. > > > >> ... or (better?) adding a size_to_shift() helper instead? > >> > >> I think most places that want the shift also want the size. > >> > >> So this can just be > >> > >> const uint64_t hpage_size = read_pmd_pagesize(); > >> const uint64_t hpage_shift = size_to_shift(hpage_size); > >> > >> > >> In size_to_shift(), you can just handle > >> > >> if (size == 0) > >> return 0; > > > > Hmm, most of tests care mainly two sizes and shiftes -- > > psize()/pshift() and pmd_pagesize() and pmd_pageshift(). > > > > Would it be better to keep both kinda of helpers and > > add size_to_shift() helper for nother hpage size then? > > Works for me as well. As long as it's consistent. > > Maybe even pmd_psize() and pmd_pshift() to match our custom psize() and pshift()? Yeap. That would be better. I'll repsin soon. -- Sincerely, Yeoreum Yun ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-09 16:40 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-07 8:15 [PATCH v2] kselftest: mm: remove HPAGE_SIZE and HPAGE_SHIFT macro Yeoreum Yun 2026-09-07 11:40 ` Sarthak Sharma 2026-09-07 12:46 ` Lorenzo Stoakes (ARM) 2026-09-07 14:36 ` David Hildenbrand (Arm) 2026-09-08 4:21 ` Sarthak Sharma 2026-09-08 8:23 ` Yeoreum Yun 2026-09-08 10:21 ` David Hildenbrand (Arm) 2026-09-09 16:40 ` Yeoreum Yun
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).