diff options
| author | Sarthak Sharma <sarthak.sharma@arm.com> | 2026-09-18 16:52:31 +0530 |
|---|---|---|
| committer | Andrew Morton <akpm@linux-foundation.org> | 2026-10-12 21:26:30 -0700 |
| commit | 32449ec2cc57bd5dc827d4e94ad9f0456e0db935 (patch) | |
| tree | 9e87f65d012ec7c903fc24019362db4644b20cca /tools/testing | |
| parent | 1d59dd1383de0061c08117a00969c563aa75bd5e (diff) | |
tools/lib/mm: move hugepage_settings out of selftests
Move hugepage_settings.[ch] from tools/testing/selftests/mm/ to
tools/lib/mm/ so the THP and HugeTLB helpers can be shared more easily
between selftests and other tools.
Keep the helpers exposed to mm selftests through vm_util.h where possible,
and use direct <mm/hugepage_settings.h> includes for files that do not
include vm_util.h. Adjust the selftests/mm build to compile the moved
implementation from its new location.
Remove the remaining kselftest dependency by including file_utils.h
directly and using EXIT_FAILURE in the signal handler.
Link: https://lore.kernel.org/20260918112234.195857-4-sarthak.sharma@arm.com
Signed-off-by: Sarthak Sharma <sarthak.sharma@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Nico Pache <npache@redhat.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Zi Yan <ziy@nvidia.com>
Diffstat (limited to 'tools/testing')
32 files changed, 13 insertions, 869 deletions
diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile index c36a9a7089bb..67882e52d4ff 100644 --- a/tools/testing/selftests/mm/Makefile +++ b/tools/testing/selftests/mm/Makefile @@ -185,8 +185,10 @@ TEST_FILES += write_hugetlb_memory.sh include ../lib.mk -$(TEST_GEN_PROGS): vm_util.c hugepage_settings.c $(top_srcdir)/tools/lib/mm/file_utils.c -$(TEST_GEN_FILES): vm_util.c hugepage_settings.c $(top_srcdir)/tools/lib/mm/file_utils.c +$(TEST_GEN_PROGS): vm_util.c $(top_srcdir)/tools/lib/mm/hugepage_settings.c \ + $(top_srcdir)/tools/lib/mm/file_utils.c +$(TEST_GEN_FILES): vm_util.c $(top_srcdir)/tools/lib/mm/hugepage_settings.c \ + $(top_srcdir)/tools/lib/mm/file_utils.c $(OUTPUT)/uffd-stress: uffd-common.c $(OUTPUT)/uffd-unit-tests: uffd-common.c diff --git a/tools/testing/selftests/mm/compaction_test.c b/tools/testing/selftests/mm/compaction_test.c index 30d4ace7155a..b3f5377119cb 100644 --- a/tools/testing/selftests/mm/compaction_test.c +++ b/tools/testing/selftests/mm/compaction_test.c @@ -15,9 +15,9 @@ #include <errno.h> #include <unistd.h> #include <string.h> +#include <mm/hugepage_settings.h> #include "kselftest.h" -#include "hugepage_settings.h" #define MAP_SIZE_MB 100 #define MAP_SIZE (MAP_SIZE_MB * 1024 * 1024) diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c index 8aa5249d9bef..3264a828575b 100644 --- a/tools/testing/selftests/mm/cow.c +++ b/tools/testing/selftests/mm/cow.c @@ -29,7 +29,6 @@ #include "../../../../mm/gup_test.h" #include "kselftest.h" #include "vm_util.h" -#include "hugepage_settings.h" static size_t pagesize; static int pagemap_fd; diff --git a/tools/testing/selftests/mm/folio_split_race_test.c b/tools/testing/selftests/mm/folio_split_race_test.c index 1960635a953e..e4660bf89b62 100644 --- a/tools/testing/selftests/mm/folio_split_race_test.c +++ b/tools/testing/selftests/mm/folio_split_race_test.c @@ -25,7 +25,6 @@ #include <unistd.h> #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" uint64_t page_size; uint64_t pmd_pagesize; diff --git a/tools/testing/selftests/mm/guard-regions.c b/tools/testing/selftests/mm/guard-regions.c index b724d62d2b75..f7d53ea3c252 100644 --- a/tools/testing/selftests/mm/guard-regions.c +++ b/tools/testing/selftests/mm/guard-regions.c @@ -21,7 +21,6 @@ #include <sys/uio.h> #include <unistd.h> #include "vm_util.h" -#include "hugepage_settings.h" #include "../pidfd/pidfd.h" diff --git a/tools/testing/selftests/mm/gup_longterm.c b/tools/testing/selftests/mm/gup_longterm.c index 510de93be681..c9d8b4491263 100644 --- a/tools/testing/selftests/mm/gup_longterm.c +++ b/tools/testing/selftests/mm/gup_longterm.c @@ -29,7 +29,6 @@ #include "../../../../mm/gup_test.h" #include "kselftest.h" #include "vm_util.h" -#include "hugepage_settings.h" static size_t pagesize; static int nr_hugetlbsizes; diff --git a/tools/testing/selftests/mm/gup_test.c b/tools/testing/selftests/mm/gup_test.c index 3f841a96f870..5f44761dbec0 100644 --- a/tools/testing/selftests/mm/gup_test.c +++ b/tools/testing/selftests/mm/gup_test.c @@ -14,7 +14,6 @@ #include <mm/gup_test.h> #include "kselftest.h" #include "vm_util.h" -#include "hugepage_settings.h" #define MB (1UL << 20) diff --git a/tools/testing/selftests/mm/hmm-tests.c b/tools/testing/selftests/mm/hmm-tests.c index e2642eca0d02..fa1a651963fd 100644 --- a/tools/testing/selftests/mm/hmm-tests.c +++ b/tools/testing/selftests/mm/hmm-tests.c @@ -10,9 +10,6 @@ * bugs. */ -#include "kselftest_harness.h" -#include "hugepage_settings.h" - #include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -33,6 +30,9 @@ #include <sys/eventfd.h> #include <linux/userfaultfd.h> #include <poll.h> +#include <mm/hugepage_settings.h> + +#include "kselftest_harness.h" /* * This is a private UAPI to the kernel test module so it isn't exported diff --git a/tools/testing/selftests/mm/hugepage_settings.c b/tools/testing/selftests/mm/hugepage_settings.c deleted file mode 100644 index 6f3abd357385..000000000000 --- a/tools/testing/selftests/mm/hugepage_settings.c +++ /dev/null @@ -1,681 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <dirent.h> -#include <fcntl.h> -#include <limits.h> -#include <signal.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include "vm_util.h" -#include "hugepage_settings.h" - -#define THP_SYSFS "/sys/kernel/mm/transparent_hugepage/" -#define MAX_SETTINGS_DEPTH 4 -static struct thp_settings settings_stack[MAX_SETTINGS_DEPTH]; -static int settings_index; -static struct thp_settings saved_settings; -static char dev_queue_read_ahead_path[PATH_MAX]; -static bool thp_settings_saved; - -static const char * const thp_enabled_strings[] = { - "never", - "always", - "inherit", - "madvise", - NULL -}; - -static const char * const thp_defrag_strings[] = { - "always", - "defer", - "defer+madvise", - "madvise", - "never", - NULL -}; - -static const char * const shmem_enabled_strings[] = { - "never", - "always", - "within_size", - "advise", - "inherit", - "deny", - "force", - NULL -}; - -static void print_file_access_error(const char *path, int ret) -{ - printf("# %s: %s (%d)\n", path, strerror(-ret), -ret); -} - -int thp_read_string(const char *name, const char * const strings[]) -{ - char path[PATH_MAX]; - char buf[256]; - char *c; - int ret; - - ret = snprintf(path, PATH_MAX, THP_SYSFS "%s", name); - if (ret >= PATH_MAX) { - printf("%s: Pathname is too long\n", __func__); - exit(EXIT_FAILURE); - } - - ret = read_file(path, buf, sizeof(buf)); - if (ret) { - print_file_access_error(path, ret); - exit(EXIT_FAILURE); - } - - c = strchr(buf, '['); - if (!c) { - printf("%s: Parse failure\n", __func__); - exit(EXIT_FAILURE); - } - - c++; - memmove(buf, c, sizeof(buf) - (c - buf)); - - c = strchr(buf, ']'); - if (!c) { - printf("%s: Parse failure\n", __func__); - exit(EXIT_FAILURE); - } - *c = '\0'; - - ret = 0; - while (strings[ret]) { - if (!strcmp(strings[ret], buf)) - return ret; - ret++; - } - - printf("Failed to parse %s\n", name); - exit(EXIT_FAILURE); -} - -void thp_write_string(const char *name, const char *val) -{ - char path[PATH_MAX]; - int ret; - - ret = snprintf(path, PATH_MAX, THP_SYSFS "%s", name); - if (ret >= PATH_MAX) { - printf("%s: Pathname is too long\n", __func__); - exit(EXIT_FAILURE); - } - ret = write_file(path, val, strlen(val) + 1); - if (ret) { - print_file_access_error(path, ret); - exit(EXIT_FAILURE); - } -} - -unsigned long thp_read_num(const char *name) -{ - char path[PATH_MAX]; - unsigned long num; - int ret; - - ret = snprintf(path, PATH_MAX, THP_SYSFS "%s", name); - if (ret >= PATH_MAX) { - printf("%s: Pathname is too long\n", __func__); - exit(EXIT_FAILURE); - } - ret = read_num(path, &num); - if (ret) { - print_file_access_error(path, ret); - exit(EXIT_FAILURE); - } - - return num; -} - -void thp_write_num(const char *name, unsigned long num) -{ - char path[PATH_MAX]; - int ret; - - ret = snprintf(path, PATH_MAX, THP_SYSFS "%s", name); - if (ret >= PATH_MAX) { - printf("%s: Pathname is too long\n", __func__); - exit(EXIT_FAILURE); - } - ret = write_num(path, num); - if (ret) { - print_file_access_error(path, ret); - exit(EXIT_FAILURE); - } -} - -void thp_read_settings(struct thp_settings *settings) -{ - unsigned long orders = thp_supported_orders(); - unsigned long shmem_orders = thp_shmem_supported_orders(); - char path[PATH_MAX]; - int i; - - *settings = (struct thp_settings) { - .thp_enabled = thp_read_string("enabled", thp_enabled_strings), - .thp_defrag = thp_read_string("defrag", thp_defrag_strings), - .shmem_enabled = - thp_read_string("shmem_enabled", shmem_enabled_strings), - .use_zero_page = thp_read_num("use_zero_page"), - }; - settings->khugepaged = (struct khugepaged_settings) { - .defrag = thp_read_num("khugepaged/defrag"), - .alloc_sleep_millisecs = - thp_read_num("khugepaged/alloc_sleep_millisecs"), - .scan_sleep_millisecs = - thp_read_num("khugepaged/scan_sleep_millisecs"), - .max_ptes_none = thp_read_num("khugepaged/max_ptes_none"), - .max_ptes_swap = thp_read_num("khugepaged/max_ptes_swap"), - .max_ptes_shared = thp_read_num("khugepaged/max_ptes_shared"), - .pages_to_scan = thp_read_num("khugepaged/pages_to_scan"), - }; - if (dev_queue_read_ahead_path[0]) { - int ret = read_num(dev_queue_read_ahead_path, - &settings->read_ahead_kb); - - if (ret) { - print_file_access_error(dev_queue_read_ahead_path, ret); - exit(EXIT_FAILURE); - } - } - - for (i = 0; i < NR_ORDERS; i++) { - if (!((1 << i) & orders)) { - settings->hugepages[i].enabled = THP_NEVER; - continue; - } - snprintf(path, PATH_MAX, "hugepages-%ukB/enabled", - (getpagesize() >> 10) << i); - settings->hugepages[i].enabled = - thp_read_string(path, thp_enabled_strings); - } - - for (i = 0; i < NR_ORDERS; i++) { - if (!((1 << i) & shmem_orders)) { - settings->shmem_hugepages[i].enabled = SHMEM_NEVER; - continue; - } - snprintf(path, PATH_MAX, "hugepages-%ukB/shmem_enabled", - (getpagesize() >> 10) << i); - settings->shmem_hugepages[i].enabled = - thp_read_string(path, shmem_enabled_strings); - } -} - -void thp_write_settings(struct thp_settings *settings) -{ - struct khugepaged_settings *khugepaged = &settings->khugepaged; - unsigned long orders = thp_supported_orders(); - unsigned long shmem_orders = thp_shmem_supported_orders(); - char path[PATH_MAX]; - int enabled; - int i; - - thp_write_string("enabled", thp_enabled_strings[settings->thp_enabled]); - thp_write_string("defrag", thp_defrag_strings[settings->thp_defrag]); - thp_write_string("shmem_enabled", - shmem_enabled_strings[settings->shmem_enabled]); - thp_write_num("use_zero_page", settings->use_zero_page); - - thp_write_num("khugepaged/defrag", khugepaged->defrag); - thp_write_num("khugepaged/alloc_sleep_millisecs", - khugepaged->alloc_sleep_millisecs); - thp_write_num("khugepaged/scan_sleep_millisecs", - khugepaged->scan_sleep_millisecs); - thp_write_num("khugepaged/max_ptes_none", khugepaged->max_ptes_none); - thp_write_num("khugepaged/max_ptes_swap", khugepaged->max_ptes_swap); - thp_write_num("khugepaged/max_ptes_shared", khugepaged->max_ptes_shared); - thp_write_num("khugepaged/pages_to_scan", khugepaged->pages_to_scan); - - if (dev_queue_read_ahead_path[0]) { - int ret = write_num(dev_queue_read_ahead_path, - settings->read_ahead_kb); - - if (ret) { - print_file_access_error(dev_queue_read_ahead_path, ret); - exit(EXIT_FAILURE); - } - } - - for (i = 0; i < NR_ORDERS; i++) { - if (!((1 << i) & orders)) - continue; - snprintf(path, PATH_MAX, "hugepages-%ukB/enabled", - (getpagesize() >> 10) << i); - enabled = settings->hugepages[i].enabled; - thp_write_string(path, thp_enabled_strings[enabled]); - } - - for (i = 0; i < NR_ORDERS; i++) { - if (!((1 << i) & shmem_orders)) - continue; - snprintf(path, PATH_MAX, "hugepages-%ukB/shmem_enabled", - (getpagesize() >> 10) << i); - enabled = settings->shmem_hugepages[i].enabled; - thp_write_string(path, shmem_enabled_strings[enabled]); - } -} - -struct thp_settings *thp_current_settings(void) -{ - if (!settings_index) { - printf("Fail: No settings set"); - exit(EXIT_FAILURE); - } - return settings_stack + settings_index - 1; -} - -void thp_push_settings(struct thp_settings *settings) -{ - if (settings_index >= MAX_SETTINGS_DEPTH) { - printf("Fail: Settings stack exceeded"); - exit(EXIT_FAILURE); - } - settings_stack[settings_index++] = *settings; - thp_write_settings(thp_current_settings()); -} - -void thp_pop_settings(void) -{ - if (settings_index <= 0) { - printf("Fail: Settings stack empty"); - exit(EXIT_FAILURE); - } - --settings_index; - thp_write_settings(thp_current_settings()); -} - -void thp_restore_settings(void) -{ - if (thp_settings_saved) - thp_write_settings(&saved_settings); -} - -static void __thp_save_settings(void) -{ - if (!thp_available()) - return; - - if (thp_settings_saved) - return; - - thp_read_settings(&saved_settings); - thp_settings_saved = true; -} - -void thp_set_read_ahead_path(char *path) -{ - if (!path) { - dev_queue_read_ahead_path[0] = '\0'; - return; - } - - strncpy(dev_queue_read_ahead_path, path, - sizeof(dev_queue_read_ahead_path)); - dev_queue_read_ahead_path[sizeof(dev_queue_read_ahead_path) - 1] = '\0'; -} - -static unsigned long __thp_supported_orders(bool is_shmem) -{ - unsigned long orders = 0; - char path[PATH_MAX]; - char buf[256]; - int ret, i; - char anon_dir[] = "enabled"; - char shmem_dir[] = "shmem_enabled"; - - for (i = 0; i < NR_ORDERS; i++) { - ret = snprintf(path, PATH_MAX, THP_SYSFS "hugepages-%ukB/%s", - (getpagesize() >> 10) << i, is_shmem ? shmem_dir : anon_dir); - if (ret >= PATH_MAX) { - printf("%s: Pathname is too long\n", __func__); - exit(EXIT_FAILURE); - } - - ret = read_file(path, buf, sizeof(buf)); - if (ret) { - if (ret != -ENOENT) { - print_file_access_error(path, ret); - exit(EXIT_FAILURE); - } - continue; - } - - orders |= 1UL << i; - } - - return orders; -} - -unsigned long thp_supported_orders(void) -{ - return __thp_supported_orders(false); -} - -unsigned long thp_shmem_supported_orders(void) -{ - return __thp_supported_orders(true); -} - -bool thp_available(void) -{ - if (access(THP_SYSFS, F_OK) != 0) - return false; - return true; -} - -bool thp_is_enabled(void) -{ - if (!thp_available()) - return false; - - int mode = thp_read_string("enabled", thp_enabled_strings); - - /* THP is considered enabled if it's either "always" or "madvise" */ - return mode == 1 || mode == 3; -} - -#define HUGETLB_MAX_NR_PAGESIZES 10 -struct hugetlb_settings { - unsigned long nr_hugepages[HUGETLB_MAX_NR_PAGESIZES]; - unsigned long sizes[HUGETLB_MAX_NR_PAGESIZES]; - unsigned long default_size; - int nr_sizes; -}; - -static struct hugetlb_settings hugetlb_saved_settings; -static bool hugetlb_settings_saved; - -int detect_hugetlb_page_sizes(unsigned long sizes[], int max) -{ - static struct hugetlb_settings *settings = &hugetlb_saved_settings; - DIR *dir; - int count = 0; - - if (settings->nr_sizes) { - if (settings->nr_sizes < max) - max = settings->nr_sizes; - for (count = 0; count < max; count++) - sizes[count] = settings->sizes[count]; - return count; - } - - dir = opendir("/sys/kernel/mm/hugepages/"); - if (!dir) - return 0; - - while (count < max) { - struct dirent *entry = readdir(dir); - size_t kb; - - if (!entry) - break; - if (entry->d_type != DT_DIR) - continue; - if (sscanf(entry->d_name, "hugepages-%zukB", &kb) != 1) - continue; - sizes[count++] = kb * 1024; - printf("# [INFO] detected hugetlb page size: %zu KiB\n", kb); - } - closedir(dir); - return count; -} - -unsigned long default_huge_page_size(void) -{ - static struct hugetlb_settings *settings = &hugetlb_saved_settings; - unsigned long hps = 0; - char *line = NULL; - size_t linelen = 0; - FILE *f; - - if (settings->default_size) - return settings->default_size; - - f = fopen("/proc/meminfo", "r"); - if (!f) - return 0; - while (getline(&line, &linelen, f) > 0) { - if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) { - hps <<= 10; - break; - } - } - - free(line); - fclose(f); - return hps; -} - -static void hugetlb_sysfs_path(char *buf, size_t buflen, - unsigned long size, const char *attr) -{ - snprintf(buf, buflen, "/sys/kernel/mm/hugepages/hugepages-%lukB/%s", - size / 1024, attr); -} - -unsigned long hugetlb_nr_pages(unsigned long size) -{ - char path[PATH_MAX]; - unsigned long nr; - int ret; - - hugetlb_sysfs_path(path, sizeof(path), size, "nr_hugepages"); - - ret = read_num(path, &nr); - if (ret) { - print_file_access_error(path, ret); - exit(EXIT_FAILURE); - } - - return nr; -} - -void hugetlb_set_nr_pages(unsigned long size, unsigned long nr) -{ - char path[PATH_MAX]; - int ret; - - hugetlb_sysfs_path(path, sizeof(path), size, "nr_hugepages"); - - ret = write_num_ignore_einval(path, nr); - if (ret) { - print_file_access_error(path, ret); - exit(EXIT_FAILURE); - } -} - -unsigned long hugetlb_free_pages(unsigned long size) -{ - char path[PATH_MAX]; - unsigned long nr; - int ret; - - hugetlb_sysfs_path(path, sizeof(path), size, "free_hugepages"); - - ret = read_num(path, &nr); - if (ret) { - print_file_access_error(path, ret); - exit(EXIT_FAILURE); - } - - return nr; -} - -unsigned long hugetlb_nr_resv_pages(unsigned long size) -{ - char path[PATH_MAX]; - unsigned long nr; - int ret; - - hugetlb_sysfs_path(path, sizeof(path), size, "resv_hugepages"); - - ret = read_num(path, &nr); - if (ret) { - print_file_access_error(path, ret); - exit(EXIT_FAILURE); - } - - return nr; -} - -static bool __hugetlb_setup(unsigned long size, unsigned long nr) -{ - unsigned long free = hugetlb_free_pages(size); - unsigned long total = hugetlb_nr_pages(size); - - if (free >= nr) - return true; - - hugetlb_set_nr_pages(size, total + (nr - free)); - - return hugetlb_free_pages(size) >= nr; -} - -bool hugetlb_setup_default(unsigned long nr) -{ - unsigned long size; - - hugetlb_save_settings(); - size = default_huge_page_size(); - if (!size) - return false; - - return __hugetlb_setup(size, nr); -} - -bool hugetlb_setup_default_exact(unsigned long nr) -{ - unsigned long size; - - hugetlb_save_settings(); - size = default_huge_page_size(); - if (!size) - return false; - - hugetlb_set_nr_pages(size, nr); - - return hugetlb_free_pages(size) == nr; -} - -unsigned long hugetlb_setup(unsigned long nr, unsigned long sizes[], - int max) -{ - unsigned long enabled[10]; - int nr_sizes = 0; - int nr_enabled; - - hugetlb_save_settings(); - - nr_enabled = detect_hugetlb_page_sizes(enabled, ARRAY_SIZE(enabled)); - if (!nr_enabled) - return 0; - - if (nr_enabled > max) { - printf("# detected %d huge page sizes, will only test %d\n", - nr_enabled, max); - nr_enabled = max; - } - - /* request nr HugeTLB pages of every size. */ - for (int i = 0; i < nr_enabled; i++) { - if (!__hugetlb_setup(enabled[i], nr)) - continue; - sizes[nr_sizes++] = enabled[i]; - } - - return nr_sizes; -} - -static void __hugetlb_save_settings(void) -{ - struct hugetlb_settings *settings = &hugetlb_saved_settings; - int nr_sizes; - - if (hugetlb_settings_saved) - return; - - settings->default_size = default_huge_page_size(); - if (!settings->default_size) - return; - - nr_sizes = detect_hugetlb_page_sizes(settings->sizes, - HUGETLB_MAX_NR_PAGESIZES); - if (!nr_sizes) { - settings->default_size = 0; - return; - } - - for (int i = 0; i < nr_sizes; i++) { - unsigned long sz = settings->sizes[i]; - - if (!sz) - continue; - settings->nr_hugepages[i] = hugetlb_nr_pages(sz); - } - - settings->nr_sizes = nr_sizes; - hugetlb_settings_saved = true; -} - -void hugetlb_restore_settings(void) -{ - struct hugetlb_settings *settings = &hugetlb_saved_settings; - - if (!hugetlb_settings_saved || !settings->default_size) - return; - - for (int i = 0; i < HUGETLB_MAX_NR_PAGESIZES; i++) { - unsigned long sz = settings->sizes[i]; - - if (!sz) - continue; - - hugetlb_set_nr_pages(sz, settings->nr_hugepages[i]); - } -} - -static void hugepage_restore_settings_atexit(void) -{ - if (thp_settings_saved) - thp_restore_settings(); - if (hugetlb_settings_saved) - hugetlb_restore_settings(); -} - -static void hugepage_restore_settings_sighandler(int sig) -{ - /* exit() will invoke the hugepage_restore_settings_atexit handler. */ - exit(KSFT_FAIL); -} - -void hugepage_save_settings(bool thp, bool hugetlb) -{ - if (!thp && !hugetlb) - return; - - if (thp) - __thp_save_settings(); - if (hugetlb) - __hugetlb_save_settings(); - - /* - * setup exit hooks to make sure THP and HugeTLB settings are - * restored on graceful and error exits and signals - */ - atexit(hugepage_restore_settings_atexit); - signal(SIGTERM, hugepage_restore_settings_sighandler); - signal(SIGINT, hugepage_restore_settings_sighandler); - signal(SIGHUP, hugepage_restore_settings_sighandler); - signal(SIGQUIT, hugepage_restore_settings_sighandler); -} diff --git a/tools/testing/selftests/mm/hugepage_settings.h b/tools/testing/selftests/mm/hugepage_settings.h deleted file mode 100644 index 548e9d288d1d..000000000000 --- a/tools/testing/selftests/mm/hugepage_settings.h +++ /dev/null @@ -1,156 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __HUGEPAGE_SETTINGS_H__ -#define __HUGEPAGE_SETTINGS_H__ - -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> - -void hugepage_save_settings(bool thp, bool hugetlb); - -/* Transparent Huge Pages (THP) */ - -enum thp_enabled { - THP_NEVER, - THP_ALWAYS, - THP_INHERIT, - THP_MADVISE, -}; - -enum thp_defrag { - THP_DEFRAG_ALWAYS, - THP_DEFRAG_DEFER, - THP_DEFRAG_DEFER_MADVISE, - THP_DEFRAG_MADVISE, - THP_DEFRAG_NEVER, -}; - -enum shmem_enabled { - SHMEM_NEVER, - SHMEM_ALWAYS, - SHMEM_WITHIN_SIZE, - SHMEM_ADVISE, - SHMEM_INHERIT, - SHMEM_DENY, - SHMEM_FORCE, -}; - -#define NR_ORDERS 20 - -struct hugepages_settings { - enum thp_enabled enabled; -}; - -struct khugepaged_settings { - bool defrag; - unsigned int alloc_sleep_millisecs; - unsigned int scan_sleep_millisecs; - unsigned int max_ptes_none; - unsigned int max_ptes_swap; - unsigned int max_ptes_shared; - unsigned long pages_to_scan; -}; - -struct shmem_hugepages_settings { - enum shmem_enabled enabled; -}; - -struct thp_settings { - enum thp_enabled thp_enabled; - enum thp_defrag thp_defrag; - enum shmem_enabled shmem_enabled; - bool use_zero_page; - struct khugepaged_settings khugepaged; - unsigned long read_ahead_kb; - struct hugepages_settings hugepages[NR_ORDERS]; - struct shmem_hugepages_settings shmem_hugepages[NR_ORDERS]; -}; - -int thp_read_string(const char *name, const char * const strings[]); -void thp_write_string(const char *name, const char *val); -unsigned long thp_read_num(const char *name); -void thp_write_num(const char *name, unsigned long num); - -void thp_write_settings(struct thp_settings *settings); -void thp_read_settings(struct thp_settings *settings); -struct thp_settings *thp_current_settings(void); -void thp_push_settings(struct thp_settings *settings); -void thp_pop_settings(void); -void thp_restore_settings(void); - -static inline void thp_save_settings(void) -{ - hugepage_save_settings(/* thp = */ true, /* hugetlb = */ false); -} - -void thp_set_read_ahead_path(char *path); -unsigned long thp_supported_orders(void); -unsigned long thp_shmem_supported_orders(void); - -bool thp_available(void); -bool thp_is_enabled(void); - -/* HugeTLB */ - -int detect_hugetlb_page_sizes(unsigned long sizes[], int max); -unsigned long default_huge_page_size(void); - -unsigned long hugetlb_nr_pages(unsigned long size); -void hugetlb_set_nr_pages(unsigned long size, unsigned long nr); -unsigned long hugetlb_free_pages(unsigned long size); -unsigned long hugetlb_nr_resv_pages(unsigned long size); - -static inline void hugetlb_save_settings(void) -{ - hugepage_save_settings(/* thp = */ false, /* hugetlb = */ true); -} - -void hugetlb_restore_settings(void); - -static inline unsigned long hugetlb_nr_default_pages(void) -{ - unsigned long size = default_huge_page_size(); - - if (!size) - return 0; - - return hugetlb_nr_pages(size); -} - -static inline void hugetlb_set_nr_default_pages(unsigned long nr) -{ - unsigned long size = default_huge_page_size(); - - if (!size) - return; - - hugetlb_set_nr_pages(size, nr); -} - -static inline unsigned long hugetlb_free_default_pages(void) -{ - unsigned long size = default_huge_page_size(); - - if (!size) - return 0; - - return hugetlb_free_pages(size); -} - -static inline bool hugetlb_available(void) -{ - return default_huge_page_size() != 0; -} - -bool hugetlb_setup_default(unsigned long nr); -bool hugetlb_setup_default_exact(unsigned long nr); -unsigned long hugetlb_setup(unsigned long nr, unsigned long sizes[], - int max); - -#define HUGETLB_SETUP_DEFAULT_PAGES(nr_pages) \ -static void __attribute__((constructor)) __hugetlb_setup_default(void) \ -{ \ - hugetlb_setup_default((nr_pages)); \ -} - -#endif /* __HUGEPAGE_SETTINGS_H__ */ diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c index 555b4b3d1430..57cf790ca478 100644 --- a/tools/testing/selftests/mm/hugetlb-madvise.c +++ b/tools/testing/selftests/mm/hugetlb-madvise.c @@ -14,7 +14,6 @@ #include <fcntl.h> #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" #define MIN_FREE_PAGES 20 #define NR_HUGE_PAGES 10 /* common number of pages to map/allocate */ diff --git a/tools/testing/selftests/mm/hugetlb-mmap.c b/tools/testing/selftests/mm/hugetlb-mmap.c index 2edbc992e6bc..8853271fc825 100644 --- a/tools/testing/selftests/mm/hugetlb-mmap.c +++ b/tools/testing/selftests/mm/hugetlb-mmap.c @@ -18,7 +18,6 @@ #include <linux/memfd.h> #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" #define LENGTH (256UL*1024*1024) #define PROTECTION (PROT_READ | PROT_WRITE) diff --git a/tools/testing/selftests/mm/hugetlb-mremap.c b/tools/testing/selftests/mm/hugetlb-mremap.c index ed3d92e862d8..9b724af66e93 100644 --- a/tools/testing/selftests/mm/hugetlb-mremap.c +++ b/tools/testing/selftests/mm/hugetlb-mremap.c @@ -26,7 +26,6 @@ #include <stdbool.h> #include "kselftest.h" #include "vm_util.h" -#include "hugepage_settings.h" #define DEFAULT_LENGTH_MB 10UL #define MB_TO_BYTES(x) (x * 1024 * 1024) diff --git a/tools/testing/selftests/mm/hugetlb-shm.c b/tools/testing/selftests/mm/hugetlb-shm.c index 3ff7f062b7eb..f4514da49e1d 100644 --- a/tools/testing/selftests/mm/hugetlb-shm.c +++ b/tools/testing/selftests/mm/hugetlb-shm.c @@ -29,7 +29,6 @@ #include <sys/mman.h> #include "vm_util.h" -#include "hugepage_settings.h" #define LENGTH (256UL*1024*1024) diff --git a/tools/testing/selftests/mm/hugetlb-soft-offline.c b/tools/testing/selftests/mm/hugetlb-soft-offline.c index ffc85b958c69..d9565219378a 100644 --- a/tools/testing/selftests/mm/hugetlb-soft-offline.c +++ b/tools/testing/selftests/mm/hugetlb-soft-offline.c @@ -22,10 +22,10 @@ #include <sys/mman.h> #include <sys/statfs.h> #include <sys/types.h> +#include <mm/hugepage_settings.h> #include "kselftest.h" #include "vm_util.h" -#include "hugepage_settings.h" #ifndef MADV_SOFT_OFFLINE #define MADV_SOFT_OFFLINE 101 diff --git a/tools/testing/selftests/mm/hugetlb_dio.c b/tools/testing/selftests/mm/hugetlb_dio.c index fb4600570e13..9495974eccbe 100644 --- a/tools/testing/selftests/mm/hugetlb_dio.c +++ b/tools/testing/selftests/mm/hugetlb_dio.c @@ -20,7 +20,6 @@ #include <sys/syscall.h> #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" #ifndef STATX_DIOALIGN #define STATX_DIOALIGN 0x00002000U diff --git a/tools/testing/selftests/mm/hugetlb_fault_after_madv.c b/tools/testing/selftests/mm/hugetlb_fault_after_madv.c index 2dc158054f66..56c5a8533e9d 100644 --- a/tools/testing/selftests/mm/hugetlb_fault_after_madv.c +++ b/tools/testing/selftests/mm/hugetlb_fault_after_madv.c @@ -10,7 +10,6 @@ #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" #define INLOOP_ITER 100 diff --git a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c index 0f15eff1da04..1d111f42dd59 100644 --- a/tools/testing/selftests/mm/hugetlb_madv_vs_map.c +++ b/tools/testing/selftests/mm/hugetlb_madv_vs_map.c @@ -14,7 +14,6 @@ #include <unistd.h> #include "vm_util.h" -#include "hugepage_settings.h" #define INLOOP_ITER 100 diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c index 6daa22f6da2f..525108cace54 100644 --- a/tools/testing/selftests/mm/khugepaged.c +++ b/tools/testing/selftests/mm/khugepaged.c @@ -22,7 +22,6 @@ #include "linux/magic.h" #include "vm_util.h" -#include "hugepage_settings.h" #define BASE_ADDR ((void *)(1UL << 30)) static unsigned long hpage_pmd_size; diff --git a/tools/testing/selftests/mm/ksm_tests.c b/tools/testing/selftests/mm/ksm_tests.c index 5fd7792a0d47..6711f4c61371 100644 --- a/tools/testing/selftests/mm/ksm_tests.c +++ b/tools/testing/selftests/mm/ksm_tests.c @@ -15,7 +15,6 @@ #include "kselftest.h" #include <include/vdso/time64.h> #include "vm_util.h" -#include "hugepage_settings.h" #define KSM_SYSFS_PATH "/sys/kernel/mm/ksm/" #define KSM_FP(s) (KSM_SYSFS_PATH s) diff --git a/tools/testing/selftests/mm/migration.c b/tools/testing/selftests/mm/migration.c index f19d53c69576..a35e2b57e05b 100644 --- a/tools/testing/selftests/mm/migration.c +++ b/tools/testing/selftests/mm/migration.c @@ -5,7 +5,6 @@ */ #include "kselftest_harness.h" -#include "hugepage_settings.h" #include <string.h> #include <pthread.h> @@ -16,6 +15,7 @@ #include <sys/types.h> #include <signal.h> #include <time.h> + #include "vm_util.h" #define TWOMEG (2<<20) diff --git a/tools/testing/selftests/mm/pagemap_ioctl.c b/tools/testing/selftests/mm/pagemap_ioctl.c index d9a4fb782ecf..03898b4f6cda 100644 --- a/tools/testing/selftests/mm/pagemap_ioctl.c +++ b/tools/testing/selftests/mm/pagemap_ioctl.c @@ -24,7 +24,6 @@ #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" #define PAGEMAP_BITS_ALL (PAGE_IS_WPALLOWED | PAGE_IS_WRITTEN | \ PAGE_IS_FILE | PAGE_IS_PRESENT | \ diff --git a/tools/testing/selftests/mm/prctl_thp_disable.c b/tools/testing/selftests/mm/prctl_thp_disable.c index 82c6e96ea6eb..f9ec1408a6e3 100644 --- a/tools/testing/selftests/mm/prctl_thp_disable.c +++ b/tools/testing/selftests/mm/prctl_thp_disable.c @@ -14,7 +14,6 @@ #include <sys/wait.h> #include "kselftest_harness.h" -#include "hugepage_settings.h" #include "vm_util.h" #ifndef PR_THP_DISABLE_EXCEPT_ADVISED diff --git a/tools/testing/selftests/mm/protection_keys.c b/tools/testing/selftests/mm/protection_keys.c index ae6e1530b354..b7882ab97683 100644 --- a/tools/testing/selftests/mm/protection_keys.c +++ b/tools/testing/selftests/mm/protection_keys.c @@ -45,8 +45,8 @@ #include <unistd.h> #include <sys/ptrace.h> #include <setjmp.h> +#include <mm/hugepage_settings.h> -#include "hugepage_settings.h" #include "pkey-helpers.h" u64 shadow_pkey_reg; diff --git a/tools/testing/selftests/mm/soft-dirty.c b/tools/testing/selftests/mm/soft-dirty.c index 5f278913c4d7..7f649b673355 100644 --- a/tools/testing/selftests/mm/soft-dirty.c +++ b/tools/testing/selftests/mm/soft-dirty.c @@ -9,7 +9,6 @@ #include "kselftest.h" #include "vm_util.h" -#include "hugepage_settings.h" #define PAGEMAP_FILE_PATH "/proc/self/pagemap" #define TEST_ITERATIONS 10000 diff --git a/tools/testing/selftests/mm/split_huge_page_test.c b/tools/testing/selftests/mm/split_huge_page_test.c index a30927514b4f..68f508c9a355 100644 --- a/tools/testing/selftests/mm/split_huge_page_test.c +++ b/tools/testing/selftests/mm/split_huge_page_test.c @@ -21,7 +21,6 @@ #include <time.h> #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" uint64_t pagesize; unsigned int pageshift; diff --git a/tools/testing/selftests/mm/thuge-gen.c b/tools/testing/selftests/mm/thuge-gen.c index 50d0805b65db..a04f588df780 100644 --- a/tools/testing/selftests/mm/thuge-gen.c +++ b/tools/testing/selftests/mm/thuge-gen.c @@ -14,7 +14,6 @@ #include <string.h> #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" #if !defined(MAP_HUGETLB) #define MAP_HUGETLB 0x40000 diff --git a/tools/testing/selftests/mm/transhuge-stress.c b/tools/testing/selftests/mm/transhuge-stress.c index 8eb0c5630e7e..96f72898ebe0 100644 --- a/tools/testing/selftests/mm/transhuge-stress.c +++ b/tools/testing/selftests/mm/transhuge-stress.c @@ -17,7 +17,6 @@ #include <sys/mman.h> #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" int backing_fd = -1; int mmap_flags = MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE; diff --git a/tools/testing/selftests/mm/uffd-common.h b/tools/testing/selftests/mm/uffd-common.h index 92a21b97f745..0723843a7626 100644 --- a/tools/testing/selftests/mm/uffd-common.h +++ b/tools/testing/selftests/mm/uffd-common.h @@ -37,7 +37,6 @@ #include "kselftest.h" #include "vm_util.h" -#include "hugepage_settings.h" #define UFFD_FLAGS (O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY) diff --git a/tools/testing/selftests/mm/uffd-wp-mremap.c b/tools/testing/selftests/mm/uffd-wp-mremap.c index 572c2516e874..c48eaab8e75c 100644 --- a/tools/testing/selftests/mm/uffd-wp-mremap.c +++ b/tools/testing/selftests/mm/uffd-wp-mremap.c @@ -7,8 +7,8 @@ #include <assert.h> #include <linux/mman.h> #include <sys/mman.h> +#include <mm/hugepage_settings.h> #include "kselftest.h" -#include "hugepage_settings.h" #include "uffd-common.h" static int pagemap_fd; diff --git a/tools/testing/selftests/mm/va_high_addr_switch.c b/tools/testing/selftests/mm/va_high_addr_switch.c index e24d7ba00b44..5a354a664d1f 100644 --- a/tools/testing/selftests/mm/va_high_addr_switch.c +++ b/tools/testing/selftests/mm/va_high_addr_switch.c @@ -11,7 +11,6 @@ #include "vm_util.h" #include "kselftest.h" -#include "hugepage_settings.h" /* * The hint addr value is used to allocate addresses diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h index fe0475f2bdf2..64a86e8a0c41 100644 --- a/tools/testing/selftests/mm/vm_util.h +++ b/tools/testing/selftests/mm/vm_util.h @@ -9,6 +9,7 @@ #include "kselftest.h" #include <linux/fs.h> #include <mm/file_utils.h> +#include <mm/hugepage_settings.h> #define BIT_ULL(nr) (1ULL << (nr)) #define PM_SOFT_DIRTY BIT_ULL(55) |
