Re: [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Just a friendly bump for review. :) Peter, any objections to this
version? I think it fairly closely matches your suggestions from v1.

On Thu, Sep 30, 2021 at 2:23 PM Axel Rasmussen <axelrasmussen@xxxxxxxxxx> wrote:
>
> Before any tests are run, in set_test_type, we decide what feature(s) we
> are going to be testing, based upon our command line arguments. However,
> the supported features are not just a function of the memory type being
> used, so this is broken.
>
> For instance, consider writeprotect support. It is "normally" supported
> for anonymous memory, but furthermore it requires that the kernel has
> CONFIG_HAVE_ARCH_USERFAULTFD_WP. So, it is *not* supported at all on
> aarch64, for example.
>
> So, this commit fixes this by querying the kernel for the set of
> features it supports in set_test_type, by opening a userfaultfd and
> issuing a UFFDIO_API ioctl. Based upon the reported features, we toggle
> what tests are enabled.
>
> Signed-off-by: Axel Rasmussen <axelrasmussen@xxxxxxxxxx>
> ---
>  tools/testing/selftests/vm/userfaultfd.c | 54 ++++++++++++++----------
>  1 file changed, 31 insertions(+), 23 deletions(-)
>
> diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c
> index 2a71a91559a7..00d1b7555865 100644
> --- a/tools/testing/selftests/vm/userfaultfd.c
> +++ b/tools/testing/selftests/vm/userfaultfd.c
> @@ -346,6 +346,16 @@ static struct uffd_test_ops hugetlb_uffd_test_ops = {
>
>  static struct uffd_test_ops *uffd_test_ops;
>
> +static inline uint64_t uffd_minor_feature(void)
> +{
> +       if (test_type == TEST_HUGETLB && map_shared)
> +               return UFFD_FEATURE_MINOR_HUGETLBFS;
> +       else if (test_type == TEST_SHMEM)
> +               return UFFD_FEATURE_MINOR_SHMEM;
> +       else
> +               return 0;
> +}
> +
>  static void userfaultfd_open(uint64_t *features)
>  {
>         struct uffdio_api uffdio_api;
> @@ -406,7 +416,7 @@ static void uffd_test_ctx_clear(void)
>         munmap_area((void **)&area_dst_alias);
>  }
>
> -static void uffd_test_ctx_init_ext(uint64_t *features)
> +static void uffd_test_ctx_init(uint64_t features)
>  {
>         unsigned long nr, cpu;
>
> @@ -418,7 +428,7 @@ static void uffd_test_ctx_init_ext(uint64_t *features)
>         uffd_test_ops->release_pages(area_src);
>         uffd_test_ops->release_pages(area_dst);
>
> -       userfaultfd_open(features);
> +       userfaultfd_open(&features);
>
>         count_verify = malloc(nr_pages * sizeof(unsigned long long));
>         if (!count_verify)
> @@ -446,11 +456,6 @@ static void uffd_test_ctx_init_ext(uint64_t *features)
>                         err("pipe");
>  }
>
> -static inline void uffd_test_ctx_init(uint64_t features)
> -{
> -       uffd_test_ctx_init_ext(&features);
> -}
> -
>  static int my_bcmp(char *str1, char *str2, size_t n)
>  {
>         unsigned long i;
> @@ -1191,7 +1196,6 @@ static int userfaultfd_minor_test(void)
>         void *expected_page;
>         char c;
>         struct uffd_stats stats = { 0 };
> -       uint64_t req_features, features_out;
>
>         if (!test_uffdio_minor)
>                 return 0;
> @@ -1199,21 +1203,7 @@ static int userfaultfd_minor_test(void)
>         printf("testing minor faults: ");
>         fflush(stdout);
>
> -       if (test_type == TEST_HUGETLB)
> -               req_features = UFFD_FEATURE_MINOR_HUGETLBFS;
> -       else if (test_type == TEST_SHMEM)
> -               req_features = UFFD_FEATURE_MINOR_SHMEM;
> -       else
> -               return 1;
> -
> -       features_out = req_features;
> -       uffd_test_ctx_init_ext(&features_out);
> -       /* If kernel reports required features aren't supported, skip test. */
> -       if ((features_out & req_features) != req_features) {
> -               printf("skipping test due to lack of feature support\n");
> -               fflush(stdout);
> -               return 0;
> -       }
> +       uffd_test_ctx_init(uffd_minor_feature());
>
>         uffdio_register.range.start = (unsigned long)area_dst_alias;
>         uffdio_register.range.len = nr_pages * page_size;
> @@ -1574,6 +1564,8 @@ unsigned long default_huge_page_size(void)
>
>  static void set_test_type(const char *type)
>  {
> +       uint64_t features = UFFD_API_FEATURES;
> +
>         if (!strcmp(type, "anon")) {
>                 test_type = TEST_ANON;
>                 uffd_test_ops = &anon_uffd_test_ops;
> @@ -1607,6 +1599,22 @@ static void set_test_type(const char *type)
>         if ((unsigned long) area_count(NULL, 0) + sizeof(unsigned long long) * 2
>             > page_size)
>                 err("Impossible to run this test");
> +
> +       /*
> +        * Whether we can test certain features depends not just on test type,
> +        * but also on whether or not this particular kernel supports the
> +        * feature.
> +        */
> +
> +       userfaultfd_open(&features);
> +
> +       test_uffdio_wp = test_uffdio_wp &&
> +               (features & UFFD_FEATURE_PAGEFAULT_FLAG_WP);
> +       test_uffdio_minor = test_uffdio_minor &&
> +               (features & uffd_minor_feature());
> +
> +       close(uffd);
> +       uffd = -1;
>  }
>
>  static void sigalrm(int sig)
> --
> 2.33.0.800.g4c38ced690-goog
>




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux