On 6/6/23 12:16 PM, John Hubbard wrote: > There are only three uffd*() routines that are used outside of the uffd > selftests. Leave these in vm_util.c, where they are available to any mm > selftest program: > > uffd_register() > uffd_unregister() > uffd_register_with_ioctls(). > > A few other uffd*() routines, however, are only used by the uffd-focused > tests found in uffd-stress.c and uffd-unit-tests.c. Move those routines > into uffd-common.c. > > Cc: Peter Xu <peterx@xxxxxxxxxx> > Acked-by: David Hildenbrand <david@xxxxxxxxxx> > Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx> Tested-by: Muhammad Usama Anjum <usama.anjum@xxxxxxxxxxxxx> > --- > tools/testing/selftests/mm/uffd-common.c | 59 ++++++++++++++++++++++++ > tools/testing/selftests/mm/uffd-common.h | 5 ++ > tools/testing/selftests/mm/vm_util.c | 59 ------------------------ > tools/testing/selftests/mm/vm_util.h | 4 -- > 4 files changed, 64 insertions(+), 63 deletions(-) > > diff --git a/tools/testing/selftests/mm/uffd-common.c b/tools/testing/selftests/mm/uffd-common.c > index 61c6250adf93..ba20d7504022 100644 > --- a/tools/testing/selftests/mm/uffd-common.c > +++ b/tools/testing/selftests/mm/uffd-common.c > @@ -616,3 +616,62 @@ int copy_page(int ufd, unsigned long offset, bool wp) > { > return __copy_page(ufd, offset, false, wp); > } > + > +int uffd_open_dev(unsigned int flags) > +{ > + int fd, uffd; > + > + fd = open("/dev/userfaultfd", O_RDWR | O_CLOEXEC); > + if (fd < 0) > + return fd; > + uffd = ioctl(fd, USERFAULTFD_IOC_NEW, flags); > + close(fd); > + > + return uffd; > +} > + > +int uffd_open_sys(unsigned int flags) > +{ > +#ifdef __NR_userfaultfd > + return syscall(__NR_userfaultfd, flags); > +#else > + return -1; > +#endif > +} > + > +int uffd_open(unsigned int flags) > +{ > + int uffd = uffd_open_sys(flags); > + > + if (uffd < 0) > + uffd = uffd_open_dev(flags); > + > + return uffd; > +} > + > +int uffd_get_features(uint64_t *features) > +{ > + struct uffdio_api uffdio_api = { .api = UFFD_API, .features = 0 }; > + /* > + * This should by default work in most kernels; the feature list > + * will be the same no matter what we pass in here. > + */ > + int fd = uffd_open(UFFD_USER_MODE_ONLY); > + > + if (fd < 0) > + /* Maybe the kernel is older than user-only mode? */ > + fd = uffd_open(0); > + > + if (fd < 0) > + return fd; > + > + if (ioctl(fd, UFFDIO_API, &uffdio_api)) { > + close(fd); > + return -errno; > + } > + > + *features = uffdio_api.features; > + close(fd); > + > + return 0; > +} > diff --git a/tools/testing/selftests/mm/uffd-common.h b/tools/testing/selftests/mm/uffd-common.h > index 6068f2346b86..197f5262fe0d 100644 > --- a/tools/testing/selftests/mm/uffd-common.h > +++ b/tools/testing/selftests/mm/uffd-common.h > @@ -110,6 +110,11 @@ int __copy_page(int ufd, unsigned long offset, bool retry, bool wp); > int copy_page(int ufd, unsigned long offset, bool wp); > void *uffd_poll_thread(void *arg); > > +int uffd_open_dev(unsigned int flags); > +int uffd_open_sys(unsigned int flags); > +int uffd_open(unsigned int flags); > +int uffd_get_features(uint64_t *features); > + > #define TEST_ANON 1 > #define TEST_HUGETLB 2 > #define TEST_SHMEM 3 > diff --git a/tools/testing/selftests/mm/vm_util.c b/tools/testing/selftests/mm/vm_util.c > index 9b06a5034808..681277615839 100644 > --- a/tools/testing/selftests/mm/vm_util.c > +++ b/tools/testing/selftests/mm/vm_util.c > @@ -242,62 +242,3 @@ int uffd_unregister(int uffd, void *addr, uint64_t len) > > return ret; > } > - > -int uffd_open_dev(unsigned int flags) > -{ > - int fd, uffd; > - > - fd = open("/dev/userfaultfd", O_RDWR | O_CLOEXEC); > - if (fd < 0) > - return fd; > - uffd = ioctl(fd, USERFAULTFD_IOC_NEW, flags); > - close(fd); > - > - return uffd; > -} > - > -int uffd_open_sys(unsigned int flags) > -{ > -#ifdef __NR_userfaultfd > - return syscall(__NR_userfaultfd, flags); > -#else > - return -1; > -#endif > -} > - > -int uffd_open(unsigned int flags) > -{ > - int uffd = uffd_open_sys(flags); > - > - if (uffd < 0) > - uffd = uffd_open_dev(flags); > - > - return uffd; > -} > - > -int uffd_get_features(uint64_t *features) > -{ > - struct uffdio_api uffdio_api = { .api = UFFD_API, .features = 0 }; > - /* > - * This should by default work in most kernels; the feature list > - * will be the same no matter what we pass in here. > - */ > - int fd = uffd_open(UFFD_USER_MODE_ONLY); > - > - if (fd < 0) > - /* Maybe the kernel is older than user-only mode? */ > - fd = uffd_open(0); > - > - if (fd < 0) > - return fd; > - > - if (ioctl(fd, UFFDIO_API, &uffdio_api)) { > - close(fd); > - return -errno; > - } > - > - *features = uffdio_api.features; > - close(fd); > - > - return 0; > -} > diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h > index 07f39ed2efba..c2d4ff798b91 100644 > --- a/tools/testing/selftests/mm/vm_util.h > +++ b/tools/testing/selftests/mm/vm_util.h > @@ -48,10 +48,6 @@ unsigned long default_huge_page_size(void); > int uffd_register(int uffd, void *addr, uint64_t len, > bool miss, bool wp, bool minor); > int uffd_unregister(int uffd, void *addr, uint64_t len); > -int uffd_open_dev(unsigned int flags); > -int uffd_open_sys(unsigned int flags); > -int uffd_open(unsigned int flags); > -int uffd_get_features(uint64_t *features); > int uffd_register_with_ioctls(int uffd, void *addr, uint64_t len, > bool miss, bool wp, bool minor, uint64_t *ioctls); > -- BR, Muhammad Usama Anjum