diff mbox series

[2/2] userfaultfd: selftests: modify selftest to use /dev/userfaultfd

Message ID 20220412202942.386981-2-axelrasmussen@google.com (mailing list archive)
State New, archived
Headers show
Series [1/2] userfaultfd: add /dev/userfaultfd for fine grained access control | expand

Commit Message

Axel Rasmussen April 12, 2022, 8:29 p.m. UTC
Prefer this new interface, but if using it fails for any reason just
fall back to using userfaultfd(2) as before.

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

Comments

Andrew Morton April 12, 2022, 8:41 p.m. UTC | #1
On Tue, 12 Apr 2022 13:29:42 -0700 Axel Rasmussen <axelrasmussen@google.com> wrote:

> Prefer this new interface, but if using it fails for any reason just
> fall back to using userfaultfd(2) as before.

This seems a poor idea - the old interface will henceforth be untested.

Why not tweak the code to test both interfaces?
Axel Rasmussen April 18, 2022, 10:16 p.m. UTC | #2
Thanks for looking Andrew. And, fair criticism.

In keeping with the status quo, I'm thinking of just adding a new
command-line argument which toggles between the two modes.

But, if I'm honest, it's starting to feel like the test has way too
many arguments... I'm tempted to refactor the test to use the
kselftest framework [1], get rid of all these command line arguments,
and just always test everything. But, this seems like a big and
perhaps controversial refactor, so I may take it up after this
series...

[1]: https://www.kernel.org/doc/html/latest/dev-tools/kselftest.html

On Tue, Apr 12, 2022 at 1:42 PM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> On Tue, 12 Apr 2022 13:29:42 -0700 Axel Rasmussen <axelrasmussen@google.com> wrote:
>
> > Prefer this new interface, but if using it fails for any reason just
> > fall back to using userfaultfd(2) as before.
>
> This seems a poor idea - the old interface will henceforth be untested.
>
> Why not tweak the code to test both interfaces?
Andrew Morton April 19, 2022, 3:32 a.m. UTC | #3
On Mon, 18 Apr 2022 15:16:02 -0700 Axel Rasmussen <axelrasmussen@google.com> wrote:

> Thanks for looking Andrew. And, fair criticism.
> 
> In keeping with the status quo, I'm thinking of just adding a new
> command-line argument which toggles between the two modes.

But I think you could tweak the test pretty simply to run itself twice.
Once with the syscall then once with the /dev interface.

I suppose that adding the commandline argument is equivalent, as long
as the upper level script/makefile invokes the test program twice.

> But, if I'm honest, it's starting to feel like the test has way too
> many arguments... I'm tempted to refactor the test to use the
> kselftest framework [1], get rid of all these command line arguments,
> and just always test everything. But, this seems like a big and
> perhaps controversial refactor, so I may take it up after this
> series...

Yes, that's a separable activity.
diff mbox series

Patch

diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c
index 92a4516f8f0d..a50c430f036c 100644
--- a/tools/testing/selftests/vm/userfaultfd.c
+++ b/tools/testing/selftests/vm/userfaultfd.c
@@ -383,13 +383,32 @@  static void assert_expected_ioctls_present(uint64_t mode, uint64_t ioctls)
 	}
 }
 
+static void __userfaultfd_open_dev(void)
+{
+	int fd;
+
+	uffd = -1;
+	fd = open("/dev/userfaultfd", O_RDWR | O_CLOEXEC);
+	if (fd < 0)
+		return;
+
+	uffd = ioctl(fd, USERFAULTFD_IOC_NEW,
+		     O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY);
+	close(fd);
+}
+
 static void userfaultfd_open(uint64_t *features)
 {
 	struct uffdio_api uffdio_api;
 
-	uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY);
+	__userfaultfd_open_dev();
+	if (uffd < 0) {
+		printf("/dev/userfaultfd failed, fallback to userfaultfd(2)\n");
+		uffd = syscall(__NR_userfaultfd,
+			       O_CLOEXEC | O_NONBLOCK | UFFD_USER_MODE_ONLY);
+	}
 	if (uffd < 0)
-		err("userfaultfd syscall not available in this kernel");
+		err("userfaultfd syscall failed");
 	uffd_flags = fcntl(uffd, F_GETFD, NULL);
 
 	uffdio_api.api = UFFD_API;