Hi Mike! On 4/29/26 2:12 AM, Mike Rapoport wrote: > From: "Mike Rapoport (Microsoft)" <[email protected]> > > uffd-unit-tests skips HugeTLB tests if there are no free huge pages > prepared by a wrapper script. > > Add setup of HugeTLB pages to the test and make sure that the original > settings are restored on the test exit. > > Replace exit() calls with _exit() to avoid restoring HugeTLB settings in > the middle of test. > > Signed-off-by: Mike Rapoport (Microsoft) <[email protected]> > --- > tools/testing/selftests/mm/uffd-unit-tests.c | 31 +++++++++++++++++--- > 1 file changed, 27 insertions(+), 4 deletions(-) > > diff --git a/tools/testing/selftests/mm/uffd-unit-tests.c > b/tools/testing/selftests/mm/uffd-unit-tests.c > index 1a33db281f8a..20e1829db91f 100644 > --- a/tools/testing/selftests/mm/uffd-unit-tests.c > +++ b/tools/testing/selftests/mm/uffd-unit-tests.c > @@ -305,7 +305,7 @@ static int pagemap_test_fork(uffd_global_test_opts_t > *gopts, bool with_event, bo > if (test_pin) > unpin_pages(&args); > /* Succeed */ > - exit(0); > + _exit(0); > } > waitpid(child, &result, 0); > > @@ -773,7 +773,7 @@ static void > uffd_sigbus_test_common(uffd_global_test_opts_t *gopts, bool wp) > err("fork"); > > if (!pid) > - exit(faulting_process(gopts, 2, wp)); > + _exit(faulting_process(gopts, 2, wp)); > > waitpid(pid, &err, 0); > if (err) > @@ -827,7 +827,7 @@ static void > uffd_events_test_common(uffd_global_test_opts_t *gopts, bool wp) > err("fork"); > > if (!pid) > - exit(faulting_process(gopts, 0, wp)); > + _exit(faulting_process(gopts, 0, wp)); > > waitpid(pid, &err, 0); > if (err) > @@ -1706,11 +1706,32 @@ static int uffd_count_tests(int n_tests, int n_mems, > const char *test_filter) > return count; > } > > +static unsigned long uffd_setup_hugetlb(void) > +{ > + unsigned long nr_hugepages, hp_size; > + > + hugetlb_save_settings(); > + hp_size = default_huge_page_size(); > + > + if (!hp_size) > + return 0; > + > + /* need twice UFFD_TEST_MEM_SIZE, one for src area and one for dst */ > + nr_hugepages = 2 * MAX(UFFD_TEST_MEM_SIZE, hp_size * 2) / hp_size; > + hugetlb_set_nr_default_pages(nr_hugepages); > + > + if (hugetlb_free_default_pages() < nr_hugepages) > + return 0; > + > + return hp_size; > +} > + > int main(int argc, char *argv[]) > { > int n_tests = sizeof(uffd_tests) / sizeof(uffd_test_case_t); > int n_mems = sizeof(mem_types) / sizeof(mem_type_t); > const char *test_filter = NULL; > + unsigned long hugepage_size; > bool list_only = false; > uffd_test_case_t *test; > mem_type_t *mem_type; > @@ -1745,6 +1766,8 @@ int main(int argc, char *argv[]) > return KSFT_PASS; > } > > + hugepage_size = uffd_setup_hugetlb(); > + > ksft_print_header(); > ksft_set_plan(uffd_count_tests(n_tests, n_mems, test_filter)); > > @@ -1771,7 +1794,7 @@ int main(int argc, char *argv[]) > uffd_test_case_ops = test->test_case_ops; > > if (mem_type->mem_flag & (MEM_HUGETLB_PRIVATE | > MEM_HUGETLB)) { > - gopts.page_size = default_huge_page_size(); > + gopts.page_size = hugepage_size; > if (gopts.page_size == 0) { > uffd_test_skip("huge page size is 0, > feature missing?");
A small nit, after this patch, uffd_setup_hugetlb() can return 0 in 2 cases: a) default_huge_page_size() == 0 b) hugetlb_free_default_pages() < nr_hugepages The skip message only covers the first case and would be misleading for the second case. Should we differentiate both these using different skip messages? > continue;

