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;


Reply via email to