summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/mm/gup_longterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/selftests/mm/gup_longterm.c')
-rw-r--r--tools/testing/selftests/mm/gup_longterm.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/tools/testing/selftests/mm/gup_longterm.c b/tools/testing/selftests/mm/gup_longterm.c
index ad168d35b23b..d50ada0c7dbf 100644
--- a/tools/testing/selftests/mm/gup_longterm.c
+++ b/tools/testing/selftests/mm/gup_longterm.c
@@ -96,13 +96,17 @@ static void do_test(int fd, size_t size, enum test_type type, bool shared)
int ret;
if (ftruncate(fd, size)) {
- ksft_test_result_fail("ftruncate() failed\n");
+ if (errno == ENOENT) {
+ skip_test_dodgy_fs("ftruncate()");
+ } else {
+ ksft_test_result_fail("ftruncate() failed (%s)\n", strerror(errno));
+ }
return;
}
if (fallocate(fd, 0, 0, size)) {
if (size == pagesize)
- ksft_test_result_fail("fallocate() failed\n");
+ ksft_test_result_fail("fallocate() failed (%s)\n", strerror(errno));
else
ksft_test_result_skip("need more free huge pages\n");
return;
@@ -112,21 +116,28 @@ static void do_test(int fd, size_t size, enum test_type type, bool shared)
shared ? MAP_SHARED : MAP_PRIVATE, fd, 0);
if (mem == MAP_FAILED) {
if (size == pagesize || shared)
- ksft_test_result_fail("mmap() failed\n");
+ ksft_test_result_fail("mmap() failed (%s)\n", strerror(errno));
else
ksft_test_result_skip("need more free huge pages\n");
return;
}
- /*
- * Fault in the page writable such that GUP-fast can eventually pin
- * it immediately.
- */
+ /* Fault in the page such that GUP-fast can pin it directly. */
memset(mem, 0, size);
switch (type) {
case TEST_TYPE_RO:
case TEST_TYPE_RO_FAST:
+ /*
+ * Cover more cases regarding unsharing decisions when
+ * long-term R/O pinning by mapping the page R/O.
+ */
+ ret = mprotect(mem, size, PROT_READ);
+ if (ret) {
+ ksft_test_result_fail("mprotect() failed (%s)\n", strerror(errno));
+ goto munmap;
+ }
+ /* FALLTHROUGH */
case TEST_TYPE_RW:
case TEST_TYPE_RW_FAST: {
struct pin_longterm_test args;
@@ -147,7 +158,7 @@ static void do_test(int fd, size_t size, enum test_type type, bool shared)
/*
* R/O pinning or pinning in a private mapping is always
* expected to work. Otherwise, we expect long-term R/W pinning
- * to only succeed for special fielesystems.
+ * to only succeed for special filesystems.
*/
should_work = !shared || !rw ||
fs_supports_writable_longterm_pinning(fs_type);
@@ -158,18 +169,20 @@ static void do_test(int fd, size_t size, enum test_type type, bool shared)
args.flags |= rw ? PIN_LONGTERM_TEST_FLAG_USE_WRITE : 0;
ret = ioctl(gup_fd, PIN_LONGTERM_TEST_START, &args);
if (ret && errno == EINVAL) {
- ksft_test_result_skip("PIN_LONGTERM_TEST_START failed\n");
+ ksft_test_result_skip("PIN_LONGTERM_TEST_START failed (EINVAL)n");
break;
} else if (ret && errno == EFAULT) {
ksft_test_result(!should_work, "Should have failed\n");
break;
} else if (ret) {
- ksft_test_result_fail("PIN_LONGTERM_TEST_START failed\n");
+ ksft_test_result_fail("PIN_LONGTERM_TEST_START failed (%s)\n",
+ strerror(errno));
break;
}
if (ioctl(gup_fd, PIN_LONGTERM_TEST_STOP))
- ksft_print_msg("[INFO] PIN_LONGTERM_TEST_STOP failed\n");
+ ksft_print_msg("[INFO] PIN_LONGTERM_TEST_STOP failed (%s)\n",
+ strerror(errno));
/*
* TODO: if the kernel ever supports long-term R/W pinning on
@@ -195,7 +208,8 @@ static void do_test(int fd, size_t size, enum test_type type, bool shared)
/* Skip on errors, as we might just lack kernel support. */
ret = io_uring_queue_init(1, &ring, 0);
if (ret < 0) {
- ksft_test_result_skip("io_uring_queue_init() failed\n");
+ ksft_test_result_skip("io_uring_queue_init() failed (%s)\n",
+ strerror(-ret));
break;
}
/*
@@ -208,13 +222,15 @@ static void do_test(int fd, size_t size, enum test_type type, bool shared)
/* Only new kernels return EFAULT. */
if (ret && (errno == ENOSPC || errno == EOPNOTSUPP ||
errno == EFAULT)) {
- ksft_test_result(!should_work, "Should have failed\n");
+ ksft_test_result(!should_work, "Should have failed (%s)\n",
+ strerror(errno));
} else if (ret) {
/*
* We might just lack support or have insufficient
* MEMLOCK limits.
*/
- ksft_test_result_skip("io_uring_register_buffers() failed\n");
+ ksft_test_result_skip("io_uring_register_buffers() failed (%s)\n",
+ strerror(-ret));
} else {
ksft_test_result(should_work, "Should have worked\n");
io_uring_unregister_buffers(&ring);
@@ -228,6 +244,7 @@ static void do_test(int fd, size_t size, enum test_type type, bool shared)
assert(false);
}
+munmap:
munmap(mem, size);
}
@@ -241,7 +258,7 @@ static void run_with_memfd(test_fn fn, const char *desc)
fd = memfd_create("test", 0);
if (fd < 0) {
- ksft_test_result_fail("memfd_create() failed\n");
+ ksft_test_result_fail("memfd_create() failed (%s)\n", strerror(errno));
return;
}
@@ -258,13 +275,13 @@ static void run_with_tmpfile(test_fn fn, const char *desc)
file = tmpfile();
if (!file) {
- ksft_test_result_fail("tmpfile() failed\n");
+ ksft_test_result_fail("tmpfile() failed (%s)\n", strerror(errno));
return;
}
fd = fileno(file);
if (fd < 0) {
- ksft_test_result_fail("fileno() failed\n");
+ ksft_test_result_fail("fileno() failed (%s)\n", strerror(errno));
goto close;
}
@@ -282,12 +299,12 @@ static void run_with_local_tmpfile(test_fn fn, const char *desc)
fd = mkstemp(filename);
if (fd < 0) {
- ksft_test_result_fail("mkstemp() failed\n");
+ ksft_test_result_fail("mkstemp() failed (%s)\n", strerror(errno));
return;
}
if (unlink(filename)) {
- ksft_test_result_fail("unlink() failed\n");
+ ksft_test_result_fail("unlink() failed (%s)\n", strerror(errno));
goto close;
}
@@ -309,7 +326,7 @@ static void run_with_memfd_hugetlb(test_fn fn, const char *desc,
fd = memfd_create("test", flags);
if (fd < 0) {
- ksft_test_result_skip("memfd_create() failed\n");
+ ksft_test_result_skip("memfd_create() failed (%s)\n", strerror(errno));
return;
}
@@ -456,5 +473,5 @@ int main(int argc, char **argv)
if (err)
ksft_exit_fail_msg("%d out of %d tests failed\n",
err, ksft_test_num());
- return ksft_exit_pass();
+ ksft_exit_pass();
}