if (test_pin)
unpin_pages(&args);
/* Succeed */
- exit(0);
+ _exit(0);
}
waitpid(child, &result, 0);
err("fork");
if (!pid)
- exit(faulting_process(gopts, 2, wp));
+ _exit(faulting_process(gopts, 2, wp));
waitpid(pid, &err, 0);
if (err)
err("fork");
if (!pid)
- exit(faulting_process(gopts, 0, wp));
+ _exit(faulting_process(gopts, 0, wp));
waitpid(pid, &err, 0);
if (err)
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;
return KSFT_PASS;
}
+ hugepage_size = uffd_setup_hugetlb();
+
ksft_print_header();
ksft_set_plan(uffd_count_tests(n_tests, n_mems, test_filter));
uffd_test_start("%s on %s", test->name, mem_type->name);
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?");
+ uffd_test_skip("not enough HugeTLB pages");
continue;
}
} else {