diff --git a/tools/testing/selftests/mm/thuge-gen.c b/tools/testing/selftests/mm/thuge-gen.c index 1007bc8aa57c..22b9c2f1c35d 100644 --- a/tools/testing/selftests/mm/thuge-gen.c +++ b/tools/testing/selftests/mm/thuge-gen.c @@ -1,17 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/* Test selecting other page sizes for mmap/shmget. - - Before running this huge pages for each huge page size must have been - reserved. - For large pages beyond MAX_PAGE_ORDER (like 1GB on x86) boot options must - be used. 1GB wouldn't be tested if it isn't available. - Also shmmax must be increased. - And you need to run as root to work around some weird permissions in shm. - And nothing using huge pages should run in parallel. - When the program aborts you may need to clean up the shm segments with - ipcrm -m by hand, like this - sudo ipcs | awk '$1 == "0x00000000" {print $2}' | xargs -n1 sudo ipcrm -m - (warning this will remove all if someone else uses them) */ +/* Test selecting other page sizes for mmap/shmget. */ #define _GNU_SOURCE #include @@ -21,8 +9,6 @@ #include #include #include -#include -#include #include #include #include @@ -38,15 +24,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 +41,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: %lu\n", ps >> 20, hugetlb_free_pages(ps)); } void test_mmap(unsigned long size, unsigned flags) @@ -97,14 +52,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 +76,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 +97,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 +109,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 +160,5 @@ int main(void) ksft_finished(); } + +SHM_LIMITS_RESTORE()