Re: [PATCH v2 46/53] selftests/mm: thuge-gen: add setup of HugeTLB pages

Luiz Capitulino
2026-04-27T20:12:14Z

On 2026-04-18 06:55, Mike Rapoport wrote:
> 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));

Are we missing a call to hugetlb_save_settings()?

>
> - 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()