From: Elizabeth Figura <zfigura@codeweavers.com>
To: Arnd Bergmann <arnd@arndb.de>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org, wine-devel@list.winehq.org,
linux-kselftest@vger.kernel.org,
"Iván Ezequiel Rodriguez" <ivanrwcm25@gmail.com>,
"Elizabeth Figura" <zfigura@codeweavers.com>
Subject: [PATCH] selftests: ntsync: add wait termination edge cases
Date: Tue, 1 Sep 2026 16:41:33 -0500 [thread overview]
Message-ID: <20260901214133.1270218-1-zfigura@codeweavers.com> (raw)
From: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
The existing tests cover timeouts that expire while blocked, but not a
deadline that has already passed, and no test exercises interruption by
a signal even though the documented behaviour is EINTR. Also extend
wait_args_validation() with an invalid flags case.
Add coverage for:
- an absolute timeout in the past, which must return ETIMEDOUT without
blocking
- a wait interrupted by a signal, which must return EINTR
- undefined bits in ntsync_wait_args::flags, which must return EINVAL
Tested on v7.3-rc1 under QEMU with CONFIG_NTSYNC=y: 15/15 pass, and the
two new tests were run 50 times each at 1, 2, 4 and 8 vCPUs with no
intermittent failures.
Signed-off-by: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
Reviewed-by: Elizabeth Figura <zfigura@codeweavers.com>
Signed-off-by: Elizabeth Figura <zfigura@codeweavers.com>
---
.../testing/selftests/drivers/ntsync/ntsync.c | 96 +++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c
index 1f0dc43bb4c0..7d944e2a9094 100644
--- a/tools/testing/selftests/drivers/ntsync/ntsync.c
+++ b/tools/testing/selftests/drivers/ntsync/ntsync.c
@@ -11,6 +11,7 @@
#include <sys/wait.h>
#include <fcntl.h>
#include <sched.h>
+#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <linux/ntsync.h>
@@ -1381,6 +1382,13 @@ TEST(wait_args_validation)
EXPECT_EQ(-1, ret);
EXPECT_EQ(EINVAL, errno);
+ wait_args.pad = 0;
+ wait_args.flags = ~NTSYNC_WAIT_REALTIME;
+ ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &wait_args);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+ wait_args.flags = 0;
+
ret = wait_any(fd2, 1, &sem, 123, &index);
EXPECT_EQ(-1, ret);
EXPECT_EQ(EINVAL, errno);
@@ -1471,4 +1479,92 @@ TEST(wait_any_monotonic_timens)
close(fd);
}
+TEST(wait_timeout_expired)
+{
+ struct ntsync_wait_args wait_args = {0};
+ struct ntsync_sem_args sem_args = {0};
+ struct timespec start, end;
+ __u64 elapsed_ns;
+ int fd, sem, ret;
+
+ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ sem_args.count = 0;
+ sem_args.max = 1;
+ sem = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_LE(0, sem);
+
+ wait_args.timeout = 0;
+ wait_args.objs = (uintptr_t)&sem;
+ wait_args.count = 1;
+ wait_args.owner = 123;
+ wait_args.index = 0xdeadbeef;
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &wait_args);
+ clock_gettime(CLOCK_MONOTONIC, &end);
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(ETIMEDOUT, errno);
+
+ elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000ULL +
+ (end.tv_nsec - start.tv_nsec);
+ EXPECT_LT(elapsed_ns, 50 * 1000000ULL);
+
+ close(sem);
+ close(fd);
+}
+
+static void ntsync_test_signal_handler(int sig)
+{
+}
+
+TEST(wait_interrupted_by_signal)
+{
+ struct ntsync_wait_args wait_args = {0};
+ struct ntsync_sem_args sem_args = {0};
+ struct sigaction sa = {0}, old_sa;
+ struct wait_args thread_args;
+ int fd, sem, ret;
+ pthread_t thread;
+
+ fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
+ ASSERT_LE(0, fd);
+
+ sem_args.count = 0;
+ sem_args.max = 1;
+ sem = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
+ EXPECT_LE(0, sem);
+
+ sa.sa_handler = ntsync_test_signal_handler;
+ ret = sigaction(SIGUSR1, &sa, &old_sa);
+ EXPECT_EQ(0, ret);
+
+ wait_args.timeout = get_abs_timeout(5000);
+ wait_args.objs = (uintptr_t)&sem;
+ wait_args.count = 1;
+ wait_args.owner = 123;
+ wait_args.index = 0xdeadbeef;
+ thread_args.fd = fd;
+ thread_args.args = &wait_args;
+ thread_args.request = NTSYNC_IOC_WAIT_ANY;
+ ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_for_thread(thread, 50);
+ EXPECT_EQ(ETIMEDOUT, ret);
+
+ ret = pthread_kill(thread, SIGUSR1);
+ EXPECT_EQ(0, ret);
+
+ ret = wait_for_thread(thread, 1000);
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(-1, thread_args.ret);
+ EXPECT_EQ(EINTR, thread_args.err);
+
+ sigaction(SIGUSR1, &old_sa, NULL);
+ close(sem);
+ close(fd);
+}
+
TEST_HARNESS_MAIN
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
--
2.53.0
next reply other threads:[~2026-09-01 21:57 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 21:41 Elizabeth Figura [this message]
-- strict thread matches above, loose matches on Subject: below --
2026-08-31 14:05 [PATCH] selftests: ntsync: add wait termination edge cases Iván Ezequiel Rodriguez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260901214133.1270218-1-zfigura@codeweavers.com \
--to=zfigura@codeweavers.com \
--cc=arnd@arndb.de \
--cc=gregkh@linuxfoundation.org \
--cc=ivanrwcm25@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=wine-devel@list.winehq.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.