linux-kselftest.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Small userfaultfd selftest fixups
@ 2021-09-30 21:23 Axel Rasmussen
  2021-09-30 21:23 ` [PATCH v2 1/3] userfaultfd/selftests: don't rely on GNU extensions for random numbers Axel Rasmussen
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Axel Rasmussen @ 2021-09-30 21:23 UTC (permalink / raw)
  To: Andrew Morton, Peter Xu, Shuah Khan
  Cc: linux-mm, linux-kselftest, linux-kernel, Axel Rasmussen

Changes from v1 -> v2:
- Substantially rewrote "fix feature support detection"; previously, it tried to
  do some larger refactor wherein the global test_uffdio_* variables were
  removed. This was controversial, so it now simply queries features in
  set_test_type, and leaves the rest of the program structure largely the same.
- The "fix calculation of expected ioctls" patch is conceptually the same as v1,
  but changed slightly to fit with the modified feature support detection in v2.
- Moved patch 3/3 to 1/3, since it is uncontroversial and could be merged on its
  own. I don't want the other two to cause merge conflicts for it in future
  versions.
- Picked up a R-B.

Axel Rasmussen (3):
  userfaultfd/selftests: don't rely on GNU extensions for random numbers
  userfaultfd/selftests: fix feature support detection
  userfaultfd/selftests: fix calculation of expected ioctls

 tools/testing/selftests/vm/userfaultfd.c | 157 +++++++++++------------
 1 file changed, 73 insertions(+), 84 deletions(-)

--
2.33.0.800.g4c38ced690-goog


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/3] userfaultfd/selftests: don't rely on GNU extensions for random numbers
  2021-09-30 21:23 [PATCH v2 0/3] Small userfaultfd selftest fixups Axel Rasmussen
@ 2021-09-30 21:23 ` Axel Rasmussen
  2021-09-30 21:23 ` [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection Axel Rasmussen
  2021-09-30 21:23 ` [PATCH v2 3/3] userfaultfd/selftests: fix calculation of expected ioctls Axel Rasmussen
  2 siblings, 0 replies; 7+ messages in thread
From: Axel Rasmussen @ 2021-09-30 21:23 UTC (permalink / raw)
  To: Andrew Morton, Peter Xu, Shuah Khan
  Cc: linux-mm, linux-kselftest, linux-kernel, Axel Rasmussen

Two arguments for doing this:

First, and maybe most importantly, the resulting code is significantly
shorter / simpler.

Then, we avoid using GNU libc extensions. Why does this matter? It makes
testing userfaultfd with the selftest easier e.g. on distros which use
something other than glibc (e.g., Alpine, which uses musl); basically,
it makes the test more portable.

Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Axel Rasmussen <axelrasmussen@google.com>
---
 tools/testing/selftests/vm/userfaultfd.c | 26 ++++--------------------
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c
index 10ab56c2484a..2a71a91559a7 100644
--- a/tools/testing/selftests/vm/userfaultfd.c
+++ b/tools/testing/selftests/vm/userfaultfd.c
@@ -57,6 +57,7 @@
 #include <assert.h>
 #include <inttypes.h>
 #include <stdint.h>
+#include <sys/random.h>
 
 #include "../kselftest.h"
 
@@ -501,22 +502,10 @@ static void continue_range(int ufd, __u64 start, __u64 len)
 static void *locking_thread(void *arg)
 {
 	unsigned long cpu = (unsigned long) arg;
-	struct random_data rand;
 	unsigned long page_nr = *(&(page_nr)); /* uninitialized warning */
-	int32_t rand_nr;
 	unsigned long long count;
-	char randstate[64];
-	unsigned int seed;
 
-	if (bounces & BOUNCE_RANDOM) {
-		seed = (unsigned int) time(NULL) - bounces;
-		if (!(bounces & BOUNCE_RACINGFAULTS))
-			seed += cpu;
-		bzero(&rand, sizeof(rand));
-		bzero(&randstate, sizeof(randstate));
-		if (initstate_r(seed, randstate, sizeof(randstate), &rand))
-			err("initstate_r failed");
-	} else {
+	if (!(bounces & BOUNCE_RANDOM)) {
 		page_nr = -bounces;
 		if (!(bounces & BOUNCE_RACINGFAULTS))
 			page_nr += cpu * nr_pages_per_cpu;
@@ -524,15 +513,8 @@ static void *locking_thread(void *arg)
 
 	while (!finished) {
 		if (bounces & BOUNCE_RANDOM) {
-			if (random_r(&rand, &rand_nr))
-				err("random_r failed");
-			page_nr = rand_nr;
-			if (sizeof(page_nr) > sizeof(rand_nr)) {
-				if (random_r(&rand, &rand_nr))
-					err("random_r failed");
-				page_nr |= (((unsigned long) rand_nr) << 16) <<
-					   16;
-			}
+			if (getrandom(&page_nr, sizeof(page_nr), 0) != sizeof(page_nr))
+				err("getrandom failed");
 		} else
 			page_nr += 1;
 		page_nr %= nr_pages;
-- 
2.33.0.800.g4c38ced690-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection
  2021-09-30 21:23 [PATCH v2 0/3] Small userfaultfd selftest fixups Axel Rasmussen
  2021-09-30 21:23 ` [PATCH v2 1/3] userfaultfd/selftests: don't rely on GNU extensions for random numbers Axel Rasmussen
@ 2021-09-30 21:23 ` Axel Rasmussen
  2021-10-20 18:28   ` Axel Rasmussen
  2021-09-30 21:23 ` [PATCH v2 3/3] userfaultfd/selftests: fix calculation of expected ioctls Axel Rasmussen
  2 siblings, 1 reply; 7+ messages in thread
From: Axel Rasmussen @ 2021-09-30 21:23 UTC (permalink / raw)
  To: Andrew Morton, Peter Xu, Shuah Khan
  Cc: linux-mm, linux-kselftest, linux-kernel, Axel Rasmussen

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@google.com>
---
 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


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/3] userfaultfd/selftests: fix calculation of expected ioctls
  2021-09-30 21:23 [PATCH v2 0/3] Small userfaultfd selftest fixups Axel Rasmussen
  2021-09-30 21:23 ` [PATCH v2 1/3] userfaultfd/selftests: don't rely on GNU extensions for random numbers Axel Rasmussen
  2021-09-30 21:23 ` [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection Axel Rasmussen
@ 2021-09-30 21:23 ` Axel Rasmussen
  2 siblings, 0 replies; 7+ messages in thread
From: Axel Rasmussen @ 2021-09-30 21:23 UTC (permalink / raw)
  To: Andrew Morton, Peter Xu, Shuah Khan
  Cc: linux-mm, linux-kselftest, linux-kernel, Axel Rasmussen

Today, we assert that the ioctls the kernel reports as supported for a
registration match a precomputed list. We decide which ioctls are
supported by examining the memory type. Then, in several locations we
"fix up" this list by adding or removing things this initial decision
got wrong.

What ioctls the kernel reports is actually a function of several things:
- The memory type
- Kernel feature support (e.g., no writeprotect on aarch64)
- The registration type (e.g., CONTINUE only supported for MINOR mode)

So, we can't fully compute this at the start, in set_test_type. It
varies per test, depending on what registration mode(s) those tests use.

Instead, introduce a new function which computes the correct list. This
centralizes the add/remove of ioctls depending on these function inputs
in one place, so we don't have to repeat ourselves in various tests.

Not only is the resulting code a bit shorter, but it fixes a real bug in
the existing code: previously, we would incorrectly require the
writeprotect ioctl to be present on aarch64, where it isn't actually
supported.

Signed-off-by: Axel Rasmussen <axelrasmussen@google.com>
---
 tools/testing/selftests/vm/userfaultfd.c | 77 ++++++++++++------------
 1 file changed, 38 insertions(+), 39 deletions(-)

diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c
index 00d1b7555865..2348b6371ec8 100644
--- a/tools/testing/selftests/vm/userfaultfd.c
+++ b/tools/testing/selftests/vm/userfaultfd.c
@@ -308,37 +308,24 @@ static void shmem_alias_mapping(__u64 *start, size_t len, unsigned long offset)
 }
 
 struct uffd_test_ops {
-	unsigned long expected_ioctls;
 	void (*allocate_area)(void **alloc_area);
 	void (*release_pages)(char *rel_area);
 	void (*alias_mapping)(__u64 *start, size_t len, unsigned long offset);
 };
 
-#define SHMEM_EXPECTED_IOCTLS		((1 << _UFFDIO_WAKE) | \
-					 (1 << _UFFDIO_COPY) | \
-					 (1 << _UFFDIO_ZEROPAGE))
-
-#define ANON_EXPECTED_IOCTLS		((1 << _UFFDIO_WAKE) | \
-					 (1 << _UFFDIO_COPY) | \
-					 (1 << _UFFDIO_ZEROPAGE) | \
-					 (1 << _UFFDIO_WRITEPROTECT))
-
 static struct uffd_test_ops anon_uffd_test_ops = {
-	.expected_ioctls = ANON_EXPECTED_IOCTLS,
 	.allocate_area	= anon_allocate_area,
 	.release_pages	= anon_release_pages,
 	.alias_mapping = noop_alias_mapping,
 };
 
 static struct uffd_test_ops shmem_uffd_test_ops = {
-	.expected_ioctls = SHMEM_EXPECTED_IOCTLS,
 	.allocate_area	= shmem_allocate_area,
 	.release_pages	= shmem_release_pages,
 	.alias_mapping = shmem_alias_mapping,
 };
 
 static struct uffd_test_ops hugetlb_uffd_test_ops = {
-	.expected_ioctls = UFFD_API_RANGE_IOCTLS_BASIC & ~(1 << _UFFDIO_CONTINUE),
 	.allocate_area	= hugetlb_allocate_area,
 	.release_pages	= hugetlb_release_pages,
 	.alias_mapping = hugetlb_alias_mapping,
@@ -356,6 +343,33 @@ static inline uint64_t uffd_minor_feature(void)
 		return 0;
 }
 
+static uint64_t get_expected_ioctls(uint64_t mode)
+{
+	uint64_t ioctls = UFFD_API_RANGE_IOCTLS;
+
+	if (test_type == TEST_HUGETLB)
+		ioctls &= ~(1 << _UFFDIO_ZEROPAGE);
+
+	if (!((mode & UFFDIO_REGISTER_MODE_WP) && test_uffdio_wp))
+		ioctls &= ~(1 << _UFFDIO_WRITEPROTECT);
+
+	if (!((mode & UFFDIO_REGISTER_MODE_MINOR) && test_uffdio_minor))
+		ioctls &= ~(1 << _UFFDIO_CONTINUE);
+
+	return ioctls;
+}
+
+static void assert_expected_ioctls_present(uint64_t mode, uint64_t ioctls)
+{
+	uint64_t expected = get_expected_ioctls(mode);
+	uint64_t actual = ioctls & expected;
+
+	if (actual != expected) {
+		err("missing ioctl(s): expected %"PRIx64" actual: %"PRIx64,
+		    expected, actual);
+	}
+}
+
 static void userfaultfd_open(uint64_t *features)
 {
 	struct uffdio_api uffdio_api;
@@ -1000,11 +1014,9 @@ static int __uffdio_zeropage(int ufd, unsigned long offset, bool retry)
 {
 	struct uffdio_zeropage uffdio_zeropage;
 	int ret;
-	unsigned long has_zeropage;
+	bool has_zeropage = get_expected_ioctls(0) & (1 << _UFFDIO_ZEROPAGE);
 	__s64 res;
 
-	has_zeropage = uffd_test_ops->expected_ioctls & (1 << _UFFDIO_ZEROPAGE);
-
 	if (offset >= nr_pages * page_size)
 		err("unexpected offset %lu", offset);
 	uffdio_zeropage.range.start = (unsigned long) area_dst + offset;
@@ -1044,7 +1056,6 @@ static int uffdio_zeropage(int ufd, unsigned long offset)
 static int userfaultfd_zeropage_test(void)
 {
 	struct uffdio_register uffdio_register;
-	unsigned long expected_ioctls;
 
 	printf("testing UFFDIO_ZEROPAGE: ");
 	fflush(stdout);
@@ -1059,9 +1070,8 @@ static int userfaultfd_zeropage_test(void)
 	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
 		err("register failure");
 
-	expected_ioctls = uffd_test_ops->expected_ioctls;
-	if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls)
-		err("unexpected missing ioctl for anon memory");
+	assert_expected_ioctls_present(
+		uffdio_register.mode, uffdio_register.ioctls);
 
 	if (uffdio_zeropage(uffd, 0))
 		if (my_bcmp(area_dst, zeropage, page_size))
@@ -1074,7 +1084,6 @@ static int userfaultfd_zeropage_test(void)
 static int userfaultfd_events_test(void)
 {
 	struct uffdio_register uffdio_register;
-	unsigned long expected_ioctls;
 	pthread_t uffd_mon;
 	int err, features;
 	pid_t pid;
@@ -1098,9 +1107,8 @@ static int userfaultfd_events_test(void)
 	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
 		err("register failure");
 
-	expected_ioctls = uffd_test_ops->expected_ioctls;
-	if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls)
-		err("unexpected missing ioctl for anon memory");
+	assert_expected_ioctls_present(
+		uffdio_register.mode, uffdio_register.ioctls);
 
 	if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, &stats))
 		err("uffd_poll_thread create");
@@ -1128,7 +1136,6 @@ static int userfaultfd_events_test(void)
 static int userfaultfd_sig_test(void)
 {
 	struct uffdio_register uffdio_register;
-	unsigned long expected_ioctls;
 	unsigned long userfaults;
 	pthread_t uffd_mon;
 	int err, features;
@@ -1152,9 +1159,8 @@ static int userfaultfd_sig_test(void)
 	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
 		err("register failure");
 
-	expected_ioctls = uffd_test_ops->expected_ioctls;
-	if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls)
-		err("unexpected missing ioctl for anon memory");
+	assert_expected_ioctls_present(
+		uffdio_register.mode, uffdio_register.ioctls);
 
 	if (faulting_process(1))
 		err("faulting process failed");
@@ -1189,7 +1195,6 @@ static int userfaultfd_sig_test(void)
 static int userfaultfd_minor_test(void)
 {
 	struct uffdio_register uffdio_register;
-	unsigned long expected_ioctls;
 	unsigned long p;
 	pthread_t uffd_mon;
 	uint8_t expected_byte;
@@ -1211,10 +1216,8 @@ static int userfaultfd_minor_test(void)
 	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
 		err("register failure");
 
-	expected_ioctls = uffd_test_ops->expected_ioctls;
-	expected_ioctls |= 1 << _UFFDIO_CONTINUE;
-	if ((uffdio_register.ioctls & expected_ioctls) != expected_ioctls)
-		err("unexpected missing ioctl(s)");
+	assert_expected_ioctls_present(
+		uffdio_register.mode, uffdio_register.ioctls);
 
 	/*
 	 * After registering with UFFD, populate the non-UFFD-registered side of
@@ -1411,8 +1414,6 @@ static int userfaultfd_stress(void)
 	pthread_attr_setstacksize(&attr, 16*1024*1024);
 
 	while (bounces--) {
-		unsigned long expected_ioctls;
-
 		printf("bounces: %d, mode:", bounces);
 		if (bounces & BOUNCE_RANDOM)
 			printf(" rnd");
@@ -1440,10 +1441,8 @@ static int userfaultfd_stress(void)
 			uffdio_register.mode |= UFFDIO_REGISTER_MODE_WP;
 		if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
 			err("register failure");
-		expected_ioctls = uffd_test_ops->expected_ioctls;
-		if ((uffdio_register.ioctls & expected_ioctls) !=
-		    expected_ioctls)
-			err("unexpected missing ioctl for anon memory");
+		assert_expected_ioctls_present(
+			uffdio_register.mode, uffdio_register.ioctls);
 
 		if (area_dst_alias) {
 			uffdio_register.range.start = (unsigned long)
-- 
2.33.0.800.g4c38ced690-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection
  2021-09-30 21:23 ` [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection Axel Rasmussen
@ 2021-10-20 18:28   ` Axel Rasmussen
  2021-10-21  1:29     ` Peter Xu
  0 siblings, 1 reply; 7+ messages in thread
From: Axel Rasmussen @ 2021-10-20 18:28 UTC (permalink / raw)
  To: Andrew Morton, Peter Xu, Shuah Khan; +Cc: Linux MM, Linuxkselftest, LKML

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@google.com> 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@google.com>
> ---
>  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
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection
  2021-10-20 18:28   ` Axel Rasmussen
@ 2021-10-21  1:29     ` Peter Xu
  2021-10-27 21:15       ` Axel Rasmussen
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Xu @ 2021-10-21  1:29 UTC (permalink / raw)
  To: Axel Rasmussen; +Cc: Andrew Morton, Shuah Khan, Linux MM, Linuxkselftest, LKML

On Wed, Oct 20, 2021 at 11:28:49AM -0700, Axel Rasmussen wrote:
> Just a friendly bump for review. :) Peter, any objections to this
> version? I think it fairly closely matches your suggestions from v1.

Isn't the whole patchset already queued by Andrew? :)

Anyway,

Reviewed-by: Peter Xu <peterx@redhat.com>

Thanks for the change!

-- 
Peter Xu


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection
  2021-10-21  1:29     ` Peter Xu
@ 2021-10-27 21:15       ` Axel Rasmussen
  0 siblings, 0 replies; 7+ messages in thread
From: Axel Rasmussen @ 2021-10-27 21:15 UTC (permalink / raw)
  To: Peter Xu; +Cc: Andrew Morton, Shuah Khan, Linux MM, Linuxkselftest, LKML

On Wed, Oct 20, 2021 at 6:29 PM Peter Xu <peterx@redhat.com> wrote:
>
> On Wed, Oct 20, 2021 at 11:28:49AM -0700, Axel Rasmussen wrote:
> > Just a friendly bump for review. :) Peter, any objections to this
> > version? I think it fairly closely matches your suggestions from v1.
>
> Isn't the whole patchset already queued by Andrew? :)

Ah, true, but I was worried he might hold it there until it got a R-B?
The process is still a bit fuzzy to me. :) Thanks for taking a look in
any case!


>
> Anyway,
>
> Reviewed-by: Peter Xu <peterx@redhat.com>
>
> Thanks for the change!
>
> --
> Peter Xu
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-10-27 21:16 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-30 21:23 [PATCH v2 0/3] Small userfaultfd selftest fixups Axel Rasmussen
2021-09-30 21:23 ` [PATCH v2 1/3] userfaultfd/selftests: don't rely on GNU extensions for random numbers Axel Rasmussen
2021-09-30 21:23 ` [PATCH v2 2/3] userfaultfd/selftests: fix feature support detection Axel Rasmussen
2021-10-20 18:28   ` Axel Rasmussen
2021-10-21  1:29     ` Peter Xu
2021-10-27 21:15       ` Axel Rasmussen
2021-09-30 21:23 ` [PATCH v2 3/3] userfaultfd/selftests: fix calculation of expected ioctls Axel Rasmussen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).