On Mon, Apr 12, 2021 at 10:17:19PM -0700, Axel Rasmussen wrote: > Currently, the context (fds, mmap-ed areas, etc.) are global. Each test > mutates this state in some way, in some cases really "clobbering it" > (e.g., the events test mremap-ing area_dst over the top of area_src, or > the minor faults tests overwriting the count_verify values in the test > areas). We run the tests in a particular order, each test is careful to > make the right assumptions about its starting state, etc. > > But, this is fragile. It's better for a test's success or failure to not > depend on what some other prior test case did to the global state. > > To that end, clear and reinitialize the test context at the start of > each test case, so whatever prior test cases did doesn't affect future > tests. > > This is particularly relevant to this series because the events test's > mremap of area_dst screws up assumptions the minor fault test was > relying on. This wasn't a problem for hugetlb, as we don't mremap in > that case. > > Signed-off-by: Axel Rasmussen <axelrasmussen@xxxxxxxxxx> > --- > tools/testing/selftests/vm/userfaultfd.c | 221 +++++++++++++---------- > 1 file changed, 127 insertions(+), 94 deletions(-) > > diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c > index 1f65c4ab7994..0ff01f437a39 100644 > --- a/tools/testing/selftests/vm/userfaultfd.c > +++ b/tools/testing/selftests/vm/userfaultfd.c > @@ -89,7 +89,8 @@ static int shm_fd; > static int huge_fd; > static char *huge_fd_off0; > static unsigned long long *count_verify; > -static int uffd, uffd_flags, finished, *pipefd; > +static int uffd = -1; > +static int uffd_flags, finished, *pipefd; > static char *area_src, *area_src_alias, *area_dst, *area_dst_alias; > static char *zeropage; > pthread_attr_t attr; > @@ -342,6 +343,121 @@ static struct uffd_test_ops hugetlb_uffd_test_ops = { > > static struct uffd_test_ops *uffd_test_ops; > > +static int userfaultfd_open(uint64_t *features) > +{ > + struct uffdio_api uffdio_api; > + > + uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); Keep UFFD_USER_MODE_ONLY? [...] > @@ -961,10 +1045,9 @@ static int userfaultfd_zeropage_test(void) > printf("testing UFFDIO_ZEROPAGE: "); > fflush(stdout); > > - uffd_test_ops->release_pages(area_dst); > - > - if (userfaultfd_open(0)) > + if (uffd_test_ctx_clear() || uffd_test_ctx_init(0)) > return 1; Would it look even nicer to init() at the entry of each test, and clear() after finish one test? > + > uffdio_register.range.start = (unsigned long) area_dst; > uffdio_register.range.len = nr_pages * page_size; > uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING; The rest looks good to me. Thanks, -- Peter Xu