* [PATCH 0/3] selftests/futex: Migrate wait functional tests to harness
@ 2026-05-25 9:19 Wake Liu
2026-05-25 9:20 ` [PATCH 1/3] selftests/futex: Migrate futex_wait " Wake Liu
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Wake Liu @ 2026-05-25 9:19 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Shuah Khan, linux-kselftest
Cc: Peter Zijlstra, Darren Hart, Davidlohr Bueso, André Almeida,
Carlos Llamas, linux-kernel, wakel
This series refactors the wait-related futex functional tests (futex_wait,
futex_wait_private_mapped_file, and futex_wait_uninitialized_heap) to
exclusively use the kselftest_harness.h framework.
This eliminates mixed usage of legacy ksft_* APIs and high-level harness
asserts, preventing crashes on older kernels, and ensures proper thread
joining.
Patch 1 migrates futex_wait.
Patch 2 migrates futex_wait_private_mapped_file.
Patch 3 migrates futex_wait_uninitialized_heap.
Wake Liu (3):
selftests/futex: Migrate futex_wait to harness
selftests/futex: Migrate futex_wait_private_mapped_file to harness
selftests/futex: Migrate futex_wait_uninitialized_heap to harness
.../selftests/futex/functional/futex_wait.c | 125 +++++++++++-------
.../futex_wait_private_mapped_file.c | 26 ++--
.../futex_wait_uninitialized_heap.c | 22 +--
3 files changed, 100 insertions(+), 73 deletions(-)
--
2.54.0.746.g67dd491aae-goog
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/3] selftests/futex: Migrate futex_wait to harness 2026-05-25 9:19 [PATCH 0/3] selftests/futex: Migrate wait functional tests to harness Wake Liu @ 2026-05-25 9:20 ` Wake Liu 2026-05-25 18:51 ` André Almeida 2026-07-05 19:54 ` [tip: locking/futex] " tip-bot2 for Wake Liu 2026-05-25 9:20 ` [PATCH 2/3] selftests/futex: Migrate futex_wait_private_mapped_file " Wake Liu 2026-05-25 9:20 ` [PATCH 3/3] selftests/futex: Migrate futex_wait_uninitialized_heap " Wake Liu 2 siblings, 2 replies; 9+ messages in thread From: Wake Liu @ 2026-05-25 9:20 UTC (permalink / raw) To: Thomas Gleixner, Ingo Molnar, Shuah Khan, linux-kselftest Cc: Peter Zijlstra, Darren Hart, Davidlohr Bueso, André Almeida, Carlos Llamas, linux-kernel, wakel Migrate futex_wait test to the kselftest harness framework, removing mixed legacy ksft_* API usages and ensuring proper thread joining. Signed-off-by: Wake Liu <wakel@google.com> --- .../selftests/futex/functional/futex_wait.c | 125 +++++++++++------- 1 file changed, 77 insertions(+), 48 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_wait.c b/tools/testing/selftests/futex/functional/futex_wait.c index 7b8879409007..ed4b040600b8 100644 --- a/tools/testing/selftests/futex/functional/futex_wait.c +++ b/tools/testing/selftests/futex/functional/futex_wait.c @@ -9,6 +9,7 @@ #include <sys/shm.h> #include <sys/mman.h> #include <fcntl.h> +#include <stdlib.h> #include "futextest.h" #include "kselftest_harness.h" @@ -19,125 +20,153 @@ void *futex; +struct waiter_args { + struct __test_metadata *_metadata; + unsigned int flags; +}; + static void *waiterfn(void *arg) { + struct waiter_args *args = (struct waiter_args *)arg; + struct __test_metadata *_metadata = args->_metadata; struct timespec to; - unsigned int flags = 0; - - if (arg) - flags = *((unsigned int *) arg); + int res; to.tv_sec = 0; to.tv_nsec = timeout_ns; - if (futex_wait(futex, 0, &to, flags)) - printf("waiter failed errno %d\n", errno); + res = futex_wait(futex, 0, &to, args->flags); + if (res) { + EXPECT_EQ(res, 0) + TH_LOG("waiter failed errno %d: %s", errno, strerror(errno)); + } + free(args); return NULL; } TEST(private_futex) { - unsigned int flags = FUTEX_PRIVATE_FLAG; + struct waiter_args *args = malloc(sizeof(*args)); u_int32_t f_private = 0; pthread_t waiter; int res; + args->_metadata = _metadata; + args->flags = FUTEX_PRIVATE_FLAG; futex = &f_private; /* Testing a private futex */ - ksft_print_dbg_msg("Calling private futex_wait on futex: %p\n", futex); - if (pthread_create(&waiter, NULL, waiterfn, (void *) &flags)) - ksft_exit_fail_msg("pthread_create failed\n"); + TH_LOG("Calling private futex_wait on futex: %p", futex); + ASSERT_EQ(pthread_create(&waiter, NULL, waiterfn, args), 0) + TH_LOG("pthread_create failed"); usleep(WAKE_WAIT_US); - ksft_print_dbg_msg("Calling private futex_wake on futex: %p\n", futex); + TH_LOG("Calling private futex_wake on futex: %p", futex); res = futex_wake(futex, 1, FUTEX_PRIVATE_FLAG); - if (res != 1) { - ksft_test_result_fail("futex_wake private returned: %d %s\n", - errno, strerror(errno)); - } else { - ksft_test_result_pass("futex_wake private succeeds\n"); - } + EXPECT_EQ(res, 1) + TH_LOG("futex_wake private returned: %d %s", res, res < 0 ? strerror(errno) : ""); + + pthread_join(waiter, NULL); } TEST(anon_page) { + struct waiter_args *args = malloc(sizeof(*args)); u_int32_t *shared_data; pthread_t waiter; int res, shm_id; + args->_metadata = _metadata; + args->flags = 0; + /* Testing an anon page shared memory */ shm_id = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666); if (shm_id < 0) { - if (errno == ENOSYS) - ksft_exit_skip("shmget syscall not supported\n"); - perror("shmget"); - exit(1); + if (errno == ENOSYS) { + free(args); + SKIP(return, "shmget syscall not supported"); + } + ASSERT_GE(shm_id, 0) + TH_LOG("shmget failed: %s", strerror(errno)); } shared_data = shmat(shm_id, NULL, 0); + if (shared_data == (void *)-1) { + free(args); + ASSERT_NE(shared_data, (void *)-1) + TH_LOG("shmat failed: %s", strerror(errno)); + } *shared_data = 0; futex = shared_data; - ksft_print_dbg_msg("Calling shared (page anon) futex_wait on futex: %p\n", futex); - if (pthread_create(&waiter, NULL, waiterfn, NULL)) - ksft_exit_fail_msg("pthread_create failed\n"); + TH_LOG("Calling shared (page anon) futex_wait on futex: %p", futex); + ASSERT_EQ(pthread_create(&waiter, NULL, waiterfn, args), 0) + TH_LOG("pthread_create failed"); usleep(WAKE_WAIT_US); - ksft_print_dbg_msg("Calling shared (page anon) futex_wake on futex: %p\n", futex); + TH_LOG("Calling shared (page anon) futex_wake on futex: %p", futex); res = futex_wake(futex, 1, 0); - if (res != 1) { - ksft_test_result_fail("futex_wake shared (page anon) returned: %d %s\n", - errno, strerror(errno)); - } else { - ksft_test_result_pass("futex_wake shared (page anon) succeeds\n"); - } + EXPECT_EQ(res, 1) + TH_LOG("futex_wake shared (page anon) returned: %d %s", res, res < 0 ? strerror(errno) : ""); + pthread_join(waiter, NULL); shmdt(shared_data); } TEST(file_backed) { + struct waiter_args *args = malloc(sizeof(*args)); u_int32_t f_private = 0; pthread_t waiter; int res, fd; void *shm; + args->_metadata = _metadata; + args->flags = 0; + /* Testing a file backed shared memory */ - fd = open(SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (fd < 0) - ksft_exit_fail_msg("open\n"); + fd = open(SHM_PATH, O_RDWR | O_CREAT, 0600); + if (fd < 0) { + free(args); + ASSERT_GE(fd, 0) + TH_LOG("open failed: %s", strerror(errno)); + } - if (ftruncate(fd, sizeof(f_private))) - ksft_exit_fail_msg("ftruncate\n"); + if (ftruncate(fd, sizeof(f_private))) { + free(args); + close(fd); + ASSERT_TRUE(0) + TH_LOG("ftruncate failed: %s", strerror(errno)); + } shm = mmap(NULL, sizeof(f_private), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (shm == MAP_FAILED) - ksft_exit_fail_msg("mmap\n"); + if (shm == MAP_FAILED) { + free(args); + close(fd); + ASSERT_NE(shm, MAP_FAILED) + TH_LOG("mmap failed: %s", strerror(errno)); + } memcpy(shm, &f_private, sizeof(f_private)); futex = shm; - ksft_print_dbg_msg("Calling shared (file backed) futex_wait on futex: %p\n", futex); - if (pthread_create(&waiter, NULL, waiterfn, NULL)) - ksft_exit_fail_msg("pthread_create failed\n"); + TH_LOG("Calling shared (file backed) futex_wait on futex: %p", futex); + ASSERT_EQ(pthread_create(&waiter, NULL, waiterfn, args), 0) + TH_LOG("pthread_create failed"); usleep(WAKE_WAIT_US); - ksft_print_dbg_msg("Calling shared (file backed) futex_wake on futex: %p\n", futex); + TH_LOG("Calling shared (file backed) futex_wake on futex: %p", futex); res = futex_wake(shm, 1, 0); - if (res != 1) { - ksft_test_result_fail("futex_wake shared (file backed) returned: %d %s\n", - errno, strerror(errno)); - } else { - ksft_test_result_pass("futex_wake shared (file backed) succeeds\n"); - } + EXPECT_EQ(res, 1) + TH_LOG("futex_wake shared (file backed) returned: %d %s", res, res < 0 ? strerror(errno) : ""); + pthread_join(waiter, NULL); munmap(shm, sizeof(f_private)); remove(SHM_PATH); close(fd); -- 2.54.0.746.g67dd491aae-goog ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] selftests/futex: Migrate futex_wait to harness 2026-05-25 9:20 ` [PATCH 1/3] selftests/futex: Migrate futex_wait " Wake Liu @ 2026-05-25 18:51 ` André Almeida 2026-05-26 1:25 ` Wake Liu 2026-07-05 19:54 ` [tip: locking/futex] " tip-bot2 for Wake Liu 1 sibling, 1 reply; 9+ messages in thread From: André Almeida @ 2026-05-25 18:51 UTC (permalink / raw) To: Wake Liu Cc: Shuah Khan, Thomas Gleixner, Peter Zijlstra, Darren Hart, linux-kselftest, Ingo Molnar, Davidlohr Bueso, Carlos Llamas, linux-kernel, kernel-dev Em 25/05/2026 06:20, Wake Liu escreveu: > Migrate futex_wait test to the kselftest harness framework, > removing mixed legacy ksft_* API usages and ensuring proper thread joining. > Why is this patchset not part of the same series that you just sent? > Signed-off-by: Wake Liu <wakel@google.com> > --- > .../selftests/futex/functional/futex_wait.c | 125 +++++++++++------- > 1 file changed, 77 insertions(+), 48 deletions(-) > > diff --git a/tools/testing/selftests/futex/functional/futex_wait.c b/tools/testing/selftests/futex/functional/futex_wait.c > index 7b8879409007..ed4b040600b8 100644 > --- a/tools/testing/selftests/futex/functional/futex_wait.c > +++ b/tools/testing/selftests/futex/functional/futex_wait.c > @@ -9,6 +9,7 @@ > #include <sys/shm.h> > #include <sys/mman.h> > #include <fcntl.h> > +#include <stdlib.h> > > #include "futextest.h" > #include "kselftest_harness.h" > @@ -19,125 +20,153 @@ > > void *futex; > > +struct waiter_args { > + struct __test_metadata *_metadata; > + unsigned int flags; > +}; > + > static void *waiterfn(void *arg) > { > + struct waiter_args *args = (struct waiter_args *)arg; > + struct __test_metadata *_metadata = args->_metadata; As much as I like the benefits of being able to properly use the harness macros in threads, I fell like we are touching private structs here. Are they safe to be used concurrently? If a child thread an the main thread fails, does that counts as two fails? Perhaps we should have a look to create a kselftest wrapper for pthread_create(). > struct timespec to; > - unsigned int flags = 0; > - > - if (arg) > - flags = *((unsigned int *) arg); > + int res; > > to.tv_sec = 0; > to.tv_nsec = timeout_ns; > > - if (futex_wait(futex, 0, &to, flags)) > - printf("waiter failed errno %d\n", errno); > + res = futex_wait(futex, 0, &to, args->flags); > + if (res) { > + EXPECT_EQ(res, 0) I have changed it to ASSERT_EQ(res, -1) just to see what happens when a child thread fails, but the test still reported PASSED: 3 / 3 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] selftests/futex: Migrate futex_wait to harness 2026-05-25 18:51 ` André Almeida @ 2026-05-26 1:25 ` Wake Liu 0 siblings, 0 replies; 9+ messages in thread From: Wake Liu @ 2026-05-26 1:25 UTC (permalink / raw) To: André Almeida Cc: Shuah Khan, Thomas Gleixner, Peter Zijlstra, Darren Hart, linux-kselftest, Ingo Molnar, Davidlohr Bueso, Carlos Llamas, linux-kernel, kernel-dev On Tue, May 26, 2026 at 2:51 AM André Almeida <andrealmeid@igalia.com> wrote: > > Em 25/05/2026 06:20, Wake Liu escreveu: > > Migrate futex_wait test to the kselftest harness framework, > > removing mixed legacy ksft_* API usages and ensuring proper thread joining. > > > > Why is this patchset not part of the same series that you just sent? > The overall scope of migrating all the remaining futex functional tests to the harness is quite large (I still have 2 series planned for requeue tests, just not finish yet lol). To keep the review process manageable and incremental, I prefer splitting them into smaller, logically grouped topic-based series (e.g., wait-related vs. requeue-related). > > Signed-off-by: Wake Liu <wakel@google.com> > > --- > > .../selftests/futex/functional/futex_wait.c | 125 +++++++++++------- > > 1 file changed, 77 insertions(+), 48 deletions(-) > > > > diff --git a/tools/testing/selftests/futex/functional/futex_wait.c b/tools/testing/selftests/futex/functional/futex_wait.c > > index 7b8879409007..ed4b040600b8 100644 > > --- a/tools/testing/selftests/futex/functional/futex_wait.c > > +++ b/tools/testing/selftests/futex/functional/futex_wait.c > > @@ -9,6 +9,7 @@ > > #include <sys/shm.h> > > #include <sys/mman.h> > > #include <fcntl.h> > > +#include <stdlib.h> > > > > #include "futextest.h" > > #include "kselftest_harness.h" > > @@ -19,125 +20,153 @@ > > > > void *futex; > > > > +struct waiter_args { > > + struct __test_metadata *_metadata; > > + unsigned int flags; > > +}; > > + > > static void *waiterfn(void *arg) > > { > > + struct waiter_args *args = (struct waiter_args *)arg; > > + struct __test_metadata *_metadata = args->_metadata; > > As much as I like the benefits of being able to properly use the harness > macros in threads, I fell like we are touching private structs here. Are > they safe to be used concurrently? If a child thread an the main thread > fails, does that counts as two fails? > > Perhaps we should have a look to create a kselftest wrapper for > pthread_create(). > Regarding concurrency safety: _metadata is allocated via MAP_SHARED in the harness, so it is shared across forks. For pthread threads, they share the same address space, so they naturally access the exact same _metadata pointer. While concurrently writing to _metadata->exit_code on failure is technically a data race under the C standard, practically it is a simple write of a constant value (KSFT_FAIL), which is robust enough for test scenarios. Stdio logging (TH_LOG) is also thread-safe in glibc (flockfile is used internally). If a child thread and the main thread both fail, it will still register as a single test failure since they both set _metadata->exit_code = KSFT_FAIL. A kselftest wrapper for pthread_create() would indeed be a great addition to the harness for cleaner thread management in the future! > > struct timespec to; > > - unsigned int flags = 0; > > - > > - if (arg) > > - flags = *((unsigned int *) arg); > > + int res; > > > > to.tv_sec = 0; > > to.tv_nsec = timeout_ns; > > > > - if (futex_wait(futex, 0, &to, flags)) > > - printf("waiter failed errno %d\n", errno); > > + res = futex_wait(futex, 0, &to, args->flags); > > + if (res) { > > + EXPECT_EQ(res, 0) > > I have changed it to ASSERT_EQ(res, -1) just to see what happens when a > child thread fails, but the test still reported PASSED: 3 / 3 I believe you might have hit a logical skip in the conditional check here: if (res) { ASSERT_EQ(res, -1); } Since futex_wait succeeds in the normal path (returning 0), the "if (res)" condition evaluates to false, and the block is skipped entirely. This is why your amended assertion was never evaluated, and the test reported PASSED. If you place the assertion outside the conditional block (e.g., immediately after futex_wait) or force a failure on success (res == 0), it will correctly trigger a SIGABRT via abort() inside the child thread, terminating the entire test process and reporting a FAILURE in the harness. -- Best Regards, Wake Liu ^ permalink raw reply [flat|nested] 9+ messages in thread
* [tip: locking/futex] selftests/futex: Migrate futex_wait to harness 2026-05-25 9:20 ` [PATCH 1/3] selftests/futex: Migrate futex_wait " Wake Liu 2026-05-25 18:51 ` André Almeida @ 2026-07-05 19:54 ` tip-bot2 for Wake Liu 1 sibling, 0 replies; 9+ messages in thread From: tip-bot2 for Wake Liu @ 2026-07-05 19:54 UTC (permalink / raw) To: linux-tip-commits; +Cc: Wake Liu, Thomas Gleixner, x86, linux-kernel The following commit has been merged into the locking/futex branch of tip: Commit-ID: 0d65d1abb5e4a3018cc3921ced750ce54943396a Gitweb: https://git.kernel.org/tip/0d65d1abb5e4a3018cc3921ced750ce54943396a Author: Wake Liu <wakel@google.com> AuthorDate: Mon, 25 May 2026 09:20:00 Committer: Thomas Gleixner <tglx@kernel.org> CommitterDate: Sun, 05 Jul 2026 21:49:17 +02:00 selftests/futex: Migrate futex_wait to harness Migrate futex_wait test to the kselftest harness framework, removing mixed legacy ksft_* API usages and ensuring proper thread joining. [ tglx: Fixup coding style ] Signed-off-by: Wake Liu <wakel@google.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260525092002.3762888-2-wakel@google.com --- tools/testing/selftests/futex/functional/futex_wait.c | 127 +++++---- 1 file changed, 80 insertions(+), 47 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_wait.c b/tools/testing/selftests/futex/functional/futex_wait.c index 7b88794..5292f5d 100644 --- a/tools/testing/selftests/futex/functional/futex_wait.c +++ b/tools/testing/selftests/futex/functional/futex_wait.c @@ -5,10 +5,11 @@ * futex cmp requeue test by André Almeida <andrealmeid@collabora.com> */ +#include <fcntl.h> #include <pthread.h> +#include <stdlib.h> #include <sys/shm.h> #include <sys/mman.h> -#include <fcntl.h> #include "futextest.h" #include "kselftest_harness.h" @@ -19,125 +20,157 @@ void *futex; +struct waiter_args { + struct __test_metadata *_metadata; + unsigned int flags; +}; + static void *waiterfn(void *arg) { + struct waiter_args *args = (struct waiter_args *)arg; + struct __test_metadata *_metadata = args->_metadata; struct timespec to; - unsigned int flags = 0; - - if (arg) - flags = *((unsigned int *) arg); + int res; to.tv_sec = 0; to.tv_nsec = timeout_ns; - if (futex_wait(futex, 0, &to, flags)) - printf("waiter failed errno %d\n", errno); + res = futex_wait(futex, 0, &to, args->flags); + if (res) { + EXPECT_EQ(res, 0) + TH_LOG("waiter failed errno %d: %s", errno, strerror(errno)); + } + free(args); return NULL; } TEST(private_futex) { - unsigned int flags = FUTEX_PRIVATE_FLAG; + struct waiter_args *args = malloc(sizeof(*args)); u_int32_t f_private = 0; pthread_t waiter; int res; + args->_metadata = _metadata; + args->flags = FUTEX_PRIVATE_FLAG; futex = &f_private; /* Testing a private futex */ - ksft_print_dbg_msg("Calling private futex_wait on futex: %p\n", futex); - if (pthread_create(&waiter, NULL, waiterfn, (void *) &flags)) - ksft_exit_fail_msg("pthread_create failed\n"); + TH_LOG("Calling private futex_wait on futex: %p", futex); + ASSERT_EQ(pthread_create(&waiter, NULL, waiterfn, args), 0) + TH_LOG("pthread_create failed"); usleep(WAKE_WAIT_US); - ksft_print_dbg_msg("Calling private futex_wake on futex: %p\n", futex); + TH_LOG("Calling private futex_wake on futex: %p", futex); res = futex_wake(futex, 1, FUTEX_PRIVATE_FLAG); - if (res != 1) { - ksft_test_result_fail("futex_wake private returned: %d %s\n", - errno, strerror(errno)); - } else { - ksft_test_result_pass("futex_wake private succeeds\n"); - } + EXPECT_EQ(res, 1) + TH_LOG("futex_wake private returned: %d %s", res, res < 0 ? strerror(errno) : ""); + + pthread_join(waiter, NULL); } TEST(anon_page) { + struct waiter_args *args = malloc(sizeof(*args)); u_int32_t *shared_data; pthread_t waiter; int res, shm_id; + args->_metadata = _metadata; + args->flags = 0; + /* Testing an anon page shared memory */ shm_id = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666); if (shm_id < 0) { - if (errno == ENOSYS) - ksft_exit_skip("shmget syscall not supported\n"); - perror("shmget"); - exit(1); + if (errno == ENOSYS) { + free(args); + SKIP(return, "shmget syscall not supported"); + } + ASSERT_GE(shm_id, 0) + TH_LOG("shmget failed: %s", strerror(errno)); } shared_data = shmat(shm_id, NULL, 0); + if (shared_data == (void *)-1) { + free(args); + ASSERT_NE(shared_data, (void *)-1) + TH_LOG("shmat failed: %s", strerror(errno)); + } *shared_data = 0; futex = shared_data; - ksft_print_dbg_msg("Calling shared (page anon) futex_wait on futex: %p\n", futex); - if (pthread_create(&waiter, NULL, waiterfn, NULL)) - ksft_exit_fail_msg("pthread_create failed\n"); + TH_LOG("Calling shared (page anon) futex_wait on futex: %p", futex); + ASSERT_EQ(pthread_create(&waiter, NULL, waiterfn, args), 0) + TH_LOG("pthread_create failed"); usleep(WAKE_WAIT_US); - ksft_print_dbg_msg("Calling shared (page anon) futex_wake on futex: %p\n", futex); + TH_LOG("Calling shared (page anon) futex_wake on futex: %p", futex); res = futex_wake(futex, 1, 0); - if (res != 1) { - ksft_test_result_fail("futex_wake shared (page anon) returned: %d %s\n", - errno, strerror(errno)); - } else { - ksft_test_result_pass("futex_wake shared (page anon) succeeds\n"); + EXPECT_EQ(res, 1) { + TH_LOG("futex_wake shared (page anon) returned: %d %s", + res, res < 0 ? strerror(errno) : ""); } + pthread_join(waiter, NULL); shmdt(shared_data); } TEST(file_backed) { + struct waiter_args *args = malloc(sizeof(*args)); u_int32_t f_private = 0; pthread_t waiter; int res, fd; void *shm; + args->_metadata = _metadata; + args->flags = 0; + /* Testing a file backed shared memory */ - fd = open(SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (fd < 0) - ksft_exit_fail_msg("open\n"); + fd = open(SHM_PATH, O_RDWR | O_CREAT, 0600); + if (fd < 0) { + free(args); + ASSERT_GE(fd, 0) + TH_LOG("open failed: %s", strerror(errno)); + } - if (ftruncate(fd, sizeof(f_private))) - ksft_exit_fail_msg("ftruncate\n"); + if (ftruncate(fd, sizeof(f_private))) { + free(args); + close(fd); + ASSERT_TRUE(0) + TH_LOG("ftruncate failed: %s", strerror(errno)); + } shm = mmap(NULL, sizeof(f_private), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (shm == MAP_FAILED) - ksft_exit_fail_msg("mmap\n"); + if (shm == MAP_FAILED) { + free(args); + close(fd); + ASSERT_NE(shm, MAP_FAILED) + TH_LOG("mmap failed: %s", strerror(errno)); + } memcpy(shm, &f_private, sizeof(f_private)); futex = shm; - ksft_print_dbg_msg("Calling shared (file backed) futex_wait on futex: %p\n", futex); - if (pthread_create(&waiter, NULL, waiterfn, NULL)) - ksft_exit_fail_msg("pthread_create failed\n"); + TH_LOG("Calling shared (file backed) futex_wait on futex: %p", futex); + ASSERT_EQ(pthread_create(&waiter, NULL, waiterfn, args), 0) + TH_LOG("pthread_create failed"); usleep(WAKE_WAIT_US); - ksft_print_dbg_msg("Calling shared (file backed) futex_wake on futex: %p\n", futex); + TH_LOG("Calling shared (file backed) futex_wake on futex: %p", futex); res = futex_wake(shm, 1, 0); - if (res != 1) { - ksft_test_result_fail("futex_wake shared (file backed) returned: %d %s\n", - errno, strerror(errno)); - } else { - ksft_test_result_pass("futex_wake shared (file backed) succeeds\n"); + EXPECT_EQ(res, 1) { + TH_LOG("futex_wake shared (file backed) returned: %d %s", + res, res < 0 ? strerror(errno) : ""); } + pthread_join(waiter, NULL); munmap(shm, sizeof(f_private)); remove(SHM_PATH); close(fd); ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] selftests/futex: Migrate futex_wait_private_mapped_file to harness 2026-05-25 9:19 [PATCH 0/3] selftests/futex: Migrate wait functional tests to harness Wake Liu 2026-05-25 9:20 ` [PATCH 1/3] selftests/futex: Migrate futex_wait " Wake Liu @ 2026-05-25 9:20 ` Wake Liu 2026-07-05 19:54 ` [tip: locking/futex] " tip-bot2 for Wake Liu 2026-05-25 9:20 ` [PATCH 3/3] selftests/futex: Migrate futex_wait_uninitialized_heap " Wake Liu 2 siblings, 1 reply; 9+ messages in thread From: Wake Liu @ 2026-05-25 9:20 UTC (permalink / raw) To: Thomas Gleixner, Ingo Molnar, Shuah Khan, linux-kselftest Cc: Peter Zijlstra, Darren Hart, Davidlohr Bueso, André Almeida, Carlos Llamas, linux-kernel, wakel Migrate futex_wait_private_mapped_file test to the kselftest harness framework, removing mixed legacy ksft_* API usages and passing test metadata to helper thread. Signed-off-by: Wake Liu <wakel@google.com> --- .../futex_wait_private_mapped_file.c | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c index 2a749f9b14eb..b4d0502a6611 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c +++ b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c @@ -26,6 +26,7 @@ #include <pthread.h> #include <libgen.h> #include <signal.h> +#include <string.h> #include "futextest.h" #include "kselftest_harness.h" @@ -41,17 +42,18 @@ struct timespec wait_timeout = { .tv_sec = 5, .tv_nsec = 0}; void *thr_futex_wait(void *arg) { + struct __test_metadata *_metadata = (struct __test_metadata *)arg; int ret; - ksft_print_dbg_msg("futex wait\n"); + TH_LOG("futex wait"); ret = futex_wait(&val, 1, &wait_timeout, 0); if (ret && errno != EWOULDBLOCK && errno != ETIMEDOUT) - ksft_exit_fail_msg("futex error.\n"); + ASSERT_TRUE(0) TH_LOG("futex error: %s", strerror(errno)); if (ret && errno == ETIMEDOUT) - ksft_exit_fail_msg("waiter timedout\n"); + ASSERT_TRUE(0) TH_LOG("waiter timedout"); - ksft_print_dbg_msg("futex_wait: ret = %d, errno = %d\n", ret, errno); + TH_LOG("futex_wait: ret = %d, errno = %d", ret, errno); return NULL; } @@ -61,22 +63,18 @@ TEST(wait_private_mapped_file) pthread_t thr; int res; - res = pthread_create(&thr, NULL, thr_futex_wait, NULL); - if (res < 0) - ksft_exit_fail_msg("pthread_create error\n"); + res = pthread_create(&thr, NULL, thr_futex_wait, _metadata); + ASSERT_EQ(res, 0) TH_LOG("pthread_create error"); - ksft_print_dbg_msg("wait a while\n"); + TH_LOG("wait a while"); usleep(WAKE_WAIT_US); val = 2; res = futex_wake(&val, 1, 0); - ksft_print_dbg_msg("futex_wake %d\n", res); - if (res != 1) - ksft_exit_fail_msg("FUTEX_WAKE didn't find the waiting thread.\n"); + TH_LOG("futex_wake %d", res); + EXPECT_EQ(res, 1) TH_LOG("FUTEX_WAKE didn't find the waiting thread"); - ksft_print_dbg_msg("join\n"); + TH_LOG("join"); pthread_join(thr, NULL); - - ksft_test_result_pass("wait_private_mapped_file"); } TEST_HARNESS_MAIN -- 2.54.0.746.g67dd491aae-goog ^ permalink raw reply [flat|nested] 9+ messages in thread
* [tip: locking/futex] selftests/futex: Migrate futex_wait_private_mapped_file to harness 2026-05-25 9:20 ` [PATCH 2/3] selftests/futex: Migrate futex_wait_private_mapped_file " Wake Liu @ 2026-07-05 19:54 ` tip-bot2 for Wake Liu 0 siblings, 0 replies; 9+ messages in thread From: tip-bot2 for Wake Liu @ 2026-07-05 19:54 UTC (permalink / raw) To: linux-tip-commits; +Cc: Wake Liu, Thomas Gleixner, x86, linux-kernel The following commit has been merged into the locking/futex branch of tip: Commit-ID: dccef66d850b49fdb8a042df59416db1d88d92d8 Gitweb: https://git.kernel.org/tip/dccef66d850b49fdb8a042df59416db1d88d92d8 Author: Wake Liu <wakel@google.com> AuthorDate: Mon, 25 May 2026 09:20:01 Committer: Thomas Gleixner <tglx@kernel.org> CommitterDate: Sun, 05 Jul 2026 21:49:17 +02:00 selftests/futex: Migrate futex_wait_private_mapped_file to harness Migrate futex_wait_private_mapped_file test to the kselftest harness framework, removing mixed legacy ksft_* API usages and passing test metadata to helper thread. [ tglx: Fixup coding style ] Signed-off-by: Wake Liu <wakel@google.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260525092002.3762888-3-wakel@google.com --- tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c index 2a749f9..a9f7a02 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c +++ b/tools/testing/selftests/futex/functional/futex_wait_private_mapped_file.c @@ -26,6 +26,7 @@ #include <pthread.h> #include <libgen.h> #include <signal.h> +#include <string.h> #include "futextest.h" #include "kselftest_harness.h" @@ -41,17 +42,22 @@ struct timespec wait_timeout = { .tv_sec = 5, .tv_nsec = 0}; void *thr_futex_wait(void *arg) { + struct __test_metadata *_metadata = (struct __test_metadata *)arg; int ret; - ksft_print_dbg_msg("futex wait\n"); + TH_LOG("futex wait"); ret = futex_wait(&val, 1, &wait_timeout, 0); - if (ret && errno != EWOULDBLOCK && errno != ETIMEDOUT) - ksft_exit_fail_msg("futex error.\n"); + if (ret && errno != EWOULDBLOCK && errno != ETIMEDOUT) { + ASSERT_TRUE(0) + TH_LOG("futex error: %s", strerror(errno)); + } - if (ret && errno == ETIMEDOUT) - ksft_exit_fail_msg("waiter timedout\n"); + if (ret && errno == ETIMEDOUT) { + ASSERT_TRUE(0) + TH_LOG("waiter timedout"); + } - ksft_print_dbg_msg("futex_wait: ret = %d, errno = %d\n", ret, errno); + TH_LOG("futex_wait: ret = %d, errno = %d", ret, errno); return NULL; } @@ -61,22 +67,20 @@ TEST(wait_private_mapped_file) pthread_t thr; int res; - res = pthread_create(&thr, NULL, thr_futex_wait, NULL); - if (res < 0) - ksft_exit_fail_msg("pthread_create error\n"); + res = pthread_create(&thr, NULL, thr_futex_wait, _metadata); + ASSERT_EQ(res, 0) + TH_LOG("pthread_create error"); - ksft_print_dbg_msg("wait a while\n"); + TH_LOG("wait a while"); usleep(WAKE_WAIT_US); val = 2; res = futex_wake(&val, 1, 0); - ksft_print_dbg_msg("futex_wake %d\n", res); - if (res != 1) - ksft_exit_fail_msg("FUTEX_WAKE didn't find the waiting thread.\n"); + TH_LOG("futex_wake %d", res); + EXPECT_EQ(res, 1) + TH_LOG("FUTEX_WAKE didn't find the waiting thread"); - ksft_print_dbg_msg("join\n"); + TH_LOG("join"); pthread_join(thr, NULL); - - ksft_test_result_pass("wait_private_mapped_file"); } TEST_HARNESS_MAIN ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] selftests/futex: Migrate futex_wait_uninitialized_heap to harness 2026-05-25 9:19 [PATCH 0/3] selftests/futex: Migrate wait functional tests to harness Wake Liu 2026-05-25 9:20 ` [PATCH 1/3] selftests/futex: Migrate futex_wait " Wake Liu 2026-05-25 9:20 ` [PATCH 2/3] selftests/futex: Migrate futex_wait_private_mapped_file " Wake Liu @ 2026-05-25 9:20 ` Wake Liu 2026-07-05 19:54 ` [tip: locking/futex] " tip-bot2 for Wake Liu 2 siblings, 1 reply; 9+ messages in thread From: Wake Liu @ 2026-05-25 9:20 UTC (permalink / raw) To: Thomas Gleixner, Ingo Molnar, Shuah Khan, linux-kselftest Cc: Peter Zijlstra, Darren Hart, Davidlohr Bueso, André Almeida, Carlos Llamas, linux-kernel, wakel Migrate futex_wait_uninitialized_heap test to the kselftest harness framework, removing mixed legacy ksft_* API usages and ensuring proper thread joining. Signed-off-by: Wake Liu <wakel@google.com> --- .../futex_wait_uninitialized_heap.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c b/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c index b07d68a67f31..ae1da2c6c8ad 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c +++ b/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c @@ -28,6 +28,7 @@ #include <errno.h> #include <linux/futex.h> #include <libgen.h> +#include <string.h> #include "futextest.h" #include "kselftest_harness.h" @@ -40,6 +41,7 @@ void *buf; void *wait_thread(void *arg) { + struct __test_metadata *_metadata = (struct __test_metadata *)arg; int res; child_ret = true; @@ -47,7 +49,7 @@ void *wait_thread(void *arg) child_blocked = 0; if (res != 0 && errno != EWOULDBLOCK) { - ksft_exit_fail_msg("futex failure\n"); + EXPECT_EQ(res, 0) TH_LOG("futex failure: %s", strerror(errno)); child_ret = false; } pthread_exit(NULL); @@ -63,21 +65,19 @@ TEST(futex_wait_uninitialized_heap) buf = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); - if (buf == (void *)-1) - ksft_exit_fail_msg("mmap\n"); + ASSERT_NE(buf, MAP_FAILED) TH_LOG("mmap failed: %s", strerror(errno)); - ret = pthread_create(&thr, NULL, wait_thread, NULL); - if (ret) - ksft_exit_fail_msg("pthread_create\n"); + ret = pthread_create(&thr, NULL, wait_thread, _metadata); + ASSERT_EQ(ret, 0) TH_LOG("pthread_create failed"); - ksft_print_dbg_msg("waiting %dus for child to return\n", WAIT_US); + TH_LOG("waiting %dus for child to return", WAIT_US); usleep(WAIT_US); - if (child_blocked) - ksft_test_result_fail("child blocked in kernel\n"); + EXPECT_EQ(child_blocked, 0) TH_LOG("child blocked in kernel"); + EXPECT_TRUE(child_ret) TH_LOG("child error"); - if (!child_ret) - ksft_test_result_fail("child error\n"); + pthread_join(thr, NULL); + munmap(buf, page_size); } TEST_HARNESS_MAIN -- 2.54.0.746.g67dd491aae-goog ^ permalink raw reply [flat|nested] 9+ messages in thread
* [tip: locking/futex] selftests/futex: Migrate futex_wait_uninitialized_heap to harness 2026-05-25 9:20 ` [PATCH 3/3] selftests/futex: Migrate futex_wait_uninitialized_heap " Wake Liu @ 2026-07-05 19:54 ` tip-bot2 for Wake Liu 0 siblings, 0 replies; 9+ messages in thread From: tip-bot2 for Wake Liu @ 2026-07-05 19:54 UTC (permalink / raw) To: linux-tip-commits; +Cc: Wake Liu, Thomas Gleixner, x86, linux-kernel The following commit has been merged into the locking/futex branch of tip: Commit-ID: 78834d8b9c99a6e2e000bb4019498ee76336887e Gitweb: https://git.kernel.org/tip/78834d8b9c99a6e2e000bb4019498ee76336887e Author: Wake Liu <wakel@google.com> AuthorDate: Mon, 25 May 2026 09:20:02 Committer: Thomas Gleixner <tglx@kernel.org> CommitterDate: Sun, 05 Jul 2026 21:49:17 +02:00 selftests/futex: Migrate futex_wait_uninitialized_heap to harness Migrate futex_wait_uninitialized_heap test to the kselftest harness framework, removing mixed legacy ksft_* API usages and ensuring proper thread joining. [ tglx: Fixup coding style ] Signed-off-by: Wake Liu <wakel@google.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260525092002.3762888-4-wakel@google.com --- tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c b/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c index b07d68a..bbffc23 100644 --- a/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c +++ b/tools/testing/selftests/futex/functional/futex_wait_uninitialized_heap.c @@ -17,17 +17,18 @@ * *****************************************************************************/ +#include <errno.h> +#include <libgen.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <linux/futex.h> #include <sys/mman.h> #include <syscall.h> #include <sys/types.h> #include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <linux/futex.h> -#include <libgen.h> #include "futextest.h" #include "kselftest_harness.h" @@ -40,6 +41,7 @@ void *buf; void *wait_thread(void *arg) { + struct __test_metadata *_metadata = (struct __test_metadata *)arg; int res; child_ret = true; @@ -47,7 +49,8 @@ void *wait_thread(void *arg) child_blocked = 0; if (res != 0 && errno != EWOULDBLOCK) { - ksft_exit_fail_msg("futex failure\n"); + EXPECT_EQ(res, 0) + TH_LOG("futex failure: %s", strerror(errno)); child_ret = false; } pthread_exit(NULL); @@ -63,21 +66,23 @@ TEST(futex_wait_uninitialized_heap) buf = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); - if (buf == (void *)-1) - ksft_exit_fail_msg("mmap\n"); + ASSERT_NE(buf, MAP_FAILED) + TH_LOG("mmap failed: %s", strerror(errno)); - ret = pthread_create(&thr, NULL, wait_thread, NULL); - if (ret) - ksft_exit_fail_msg("pthread_create\n"); + ret = pthread_create(&thr, NULL, wait_thread, _metadata); + ASSERT_EQ(ret, 0) + TH_LOG("pthread_create failed"); - ksft_print_dbg_msg("waiting %dus for child to return\n", WAIT_US); + TH_LOG("waiting %dus for child to return", WAIT_US); usleep(WAIT_US); - if (child_blocked) - ksft_test_result_fail("child blocked in kernel\n"); + EXPECT_EQ(child_blocked, 0) + TH_LOG("child blocked in kernel"); + EXPECT_TRUE(child_ret) + TH_LOG("child error"); - if (!child_ret) - ksft_test_result_fail("child error\n"); + pthread_join(thr, NULL); + munmap(buf, page_size); } TEST_HARNESS_MAIN ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-07-05 19:54 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-05-25 9:19 [PATCH 0/3] selftests/futex: Migrate wait functional tests to harness Wake Liu 2026-05-25 9:20 ` [PATCH 1/3] selftests/futex: Migrate futex_wait " Wake Liu 2026-05-25 18:51 ` André Almeida 2026-05-26 1:25 ` Wake Liu 2026-07-05 19:54 ` [tip: locking/futex] " tip-bot2 for Wake Liu 2026-05-25 9:20 ` [PATCH 2/3] selftests/futex: Migrate futex_wait_private_mapped_file " Wake Liu 2026-07-05 19:54 ` [tip: locking/futex] " tip-bot2 for Wake Liu 2026-05-25 9:20 ` [PATCH 3/3] selftests/futex: Migrate futex_wait_uninitialized_heap " Wake Liu 2026-07-05 19:54 ` [tip: locking/futex] " tip-bot2 for Wake Liu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome