mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Wake Liu <wakel@google.com>
To: Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
	Shuah Khan <shuah@kernel.org>,
	 linux-kselftest@vger.kernel.org
Cc: "Peter Zijlstra" <peterz@infradead.org>,
	"Darren Hart" <dvhart@infradead.org>,
	"Davidlohr Bueso" <dave@stgolabs.net>,
	"André Almeida" <andrealmeid@igalia.com>,
	"Carlos Llamas" <cmllamas@google.com>,
	linux-kernel@vger.kernel.org, wakel@google.com
Subject: [PATCH 6/7] selftests/futex: Migrate futex_priv_hash to harness
Date: Mon,  1 Jun 2026 06:51:25 +0000	[thread overview]
Message-ID: <20260601065126.3623867-7-wakel@google.com> (raw)
In-Reply-To: <20260601065126.3623867-1-wakel@google.com>

Migrate futex_priv_hash test to the kselftest harness framework,
removing mixed legacy ksft_* API usages and passing test metadata
to all helper functions.

Signed-off-by: Wake Liu <wakel@google.com>
---
 .../futex/functional/futex_priv_hash.c        | 160 +++++++++---------
 1 file changed, 78 insertions(+), 82 deletions(-)

diff --git a/tools/testing/selftests/futex/functional/futex_priv_hash.c b/tools/testing/selftests/futex/functional/futex_priv_hash.c
index e8079d7c65e8..60d500598f2b 100644
--- a/tools/testing/selftests/futex/functional/futex_priv_hash.c
+++ b/tools/testing/selftests/futex/functional/futex_priv_hash.c
@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
 
 #include <linux/prctl.h>
 #include <sys/prctl.h>
@@ -39,31 +40,27 @@ static int futex_hash_slots_get(void)
 	return prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_GET_SLOTS);
 }
 
-static void futex_hash_slots_set_verify(int slots)
+static void futex_hash_slots_set_verify(struct __test_metadata *_metadata, int slots)
 {
 	int ret;
 
 	ret = futex_hash_slots_set(slots);
-	if (ret != 0) {
-		ksft_test_result_fail("Failed to set slots to %d: %m\n", slots);
-		ksft_finished();
-	}
+	ASSERT_EQ(ret, 0)
+		TH_LOG("Failed to set slots to %d: %s", slots, strerror(errno));
+
 	ret = futex_hash_slots_get();
-	if (ret != slots) {
-		ksft_test_result_fail("Set %d slots but PR_FUTEX_HASH_GET_SLOTS returns: %d, %m\n",
-		       slots, ret);
-		ksft_finished();
-	}
-	ksft_test_result_pass("SET and GET slots %d passed\n", slots);
+	ASSERT_EQ(ret, slots)
+		TH_LOG("Set %d slots but PR_FUTEX_HASH_GET_SLOTS returns: %d, %s",
+		       slots, ret, strerror(errno));
 }
 
-static void futex_hash_slots_set_must_fail(int slots)
+static void futex_hash_slots_set_must_fail(struct __test_metadata *_metadata, int slots)
 {
 	int ret;
 
 	ret = futex_hash_slots_set(slots);
-	ksft_test_result(ret < 0, "futex_hash_slots_set(%d)\n",
-			 slots);
+	EXPECT_LT(ret, 0)
+		TH_LOG("futex_hash_slots_set(%d) should fail but succeeded", slots);
 }
 
 static void *thread_return_fn(void *arg)
@@ -82,32 +79,32 @@ static void *thread_lock_fn(void *arg)
 	return NULL;
 }
 
-static void create_max_threads(void *(*thread_fn)(void *))
+static void create_max_threads(struct __test_metadata *_metadata, void *(*thread_fn)(void *))
 {
 	int i, ret;
 
 	for (i = 0; i < MAX_THREADS; i++) {
 		ret = pthread_create(&threads[i], NULL, thread_fn, NULL);
-		if (ret)
-			ksft_exit_fail_msg("pthread_create failed: %m\n");
+		ASSERT_EQ(ret, 0)
+			TH_LOG("pthread_create failed: %s", strerror(errno));
 	}
 }
 
-static void join_max_threads(void)
+static void join_max_threads(struct __test_metadata *_metadata)
 {
 	int i, ret;
 
 	for (i = 0; i < MAX_THREADS; i++) {
 		ret = pthread_join(threads[i], NULL);
-		if (ret)
-			ksft_exit_fail_msg("pthread_join failed for thread %d\n", i);
+		ASSERT_EQ(ret, 0)
+			TH_LOG("pthread_join failed for thread %d: %s", i, strerror(errno));
 	}
 }
 
 #define SEC_IN_NSEC	1000000000
 #define MSEC_IN_NSEC	1000000
 
-static void futex_dummy_op(void)
+static void futex_dummy_op(struct __test_metadata *_metadata)
 {
 	pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 	struct timespec timeout;
@@ -121,11 +118,11 @@ static void futex_dummy_op(void)
 		timeout.tv_sec++;
 	}
 	ret = pthread_mutex_timedlock(&lock, &timeout);
-	if (ret == 0)
-		ksft_exit_fail_msg("Successfully locked an already locked mutex.\n");
+	ASSERT_NE(ret, 0)
+		TH_LOG("Successfully locked an already locked mutex");
 
-	if (ret != ETIMEDOUT)
-		ksft_exit_fail_msg("pthread_mutex_timedlock() did not timeout: %d.\n", ret);
+	ASSERT_EQ(ret, ETIMEDOUT)
+		TH_LOG("pthread_mutex_timedlock() did not timeout: %d", ret);
 }
 
 static const char *test_msg_auto_create = "Automatic hash bucket init on thread creation.\n";
@@ -140,50 +137,45 @@ TEST(priv_hash)
 	ret = pthread_mutexattr_init(&mutex_attr_pi);
 	ret |= pthread_mutexattr_setprotocol(&mutex_attr_pi, PTHREAD_PRIO_INHERIT);
 	ret |= pthread_mutex_init(&global_lock, &mutex_attr_pi);
-	if (ret != 0) {
-		ksft_exit_fail_msg("Failed to initialize pthread mutex.\n");
-	}
+	ASSERT_EQ(ret, 0)
+		TH_LOG("Failed to initialize pthread mutex");
+
 	/* First thread, expect to be 0, not yet initialized */
 	ret = futex_hash_slots_get();
-	if (ret != 0)
-		ksft_exit_fail_msg("futex_hash_slots_get() failed: %d, %m\n", ret);
+	ASSERT_EQ(ret, 0)
+		TH_LOG("futex_hash_slots_get() failed: %d, %s", ret, strerror(errno));
 
-	ksft_test_result_pass("Basic get slots and immutable status.\n");
 	ret = pthread_create(&threads[0], NULL, thread_return_fn, NULL);
-	if (ret != 0)
-		ksft_exit_fail_msg("pthread_create() failed: %d, %m\n", ret);
+	ASSERT_EQ(ret, 0)
+		TH_LOG("pthread_create() failed: %d, %s", ret, strerror(errno));
 
 	ret = pthread_join(threads[0], NULL);
-	if (ret != 0)
-		ksft_exit_fail_msg("pthread_join() failed: %d, %m\n", ret);
+	ASSERT_EQ(ret, 0)
+		TH_LOG("pthread_join() failed: %d, %s", ret, strerror(errno));
 
 	/* First thread, has to initialize private hash */
 	futex_slots1 = futex_hash_slots_get();
-	if (futex_slots1 <= 0) {
-		ksft_print_msg("Current hash buckets: %d\n", futex_slots1);
-		ksft_exit_fail_msg("%s", test_msg_auto_create);
-	}
-
-	ksft_test_result_pass("%s", test_msg_auto_create);
+	EXPECT_GT(futex_slots1, 0)
+		TH_LOG("Current hash buckets: %d. %s", futex_slots1, test_msg_auto_create);
 
 	online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
 	ret = pthread_barrier_init(&barrier_main, NULL, MAX_THREADS + 1);
-	if (ret != 0)
-		ksft_exit_fail_msg("pthread_barrier_init failed: %m.\n");
+	ASSERT_EQ(ret, 0)
+		TH_LOG("pthread_barrier_init failed: %s", strerror(errno));
 
 	ret = pthread_mutex_lock(&global_lock);
-	if (ret != 0)
-		ksft_exit_fail_msg("pthread_mutex_lock failed: %m.\n");
+	ASSERT_EQ(ret, 0)
+		TH_LOG("pthread_mutex_lock failed: %s", strerror(errno));
 
 	counter = 0;
-	create_max_threads(thread_lock_fn);
+	create_max_threads(_metadata, thread_lock_fn);
 	pthread_barrier_wait(&barrier_main);
 
 	/*
 	 * The current default size of hash buckets is 16. The auto increase
 	 * works only if more than 16 CPUs are available.
 	 */
-	ksft_print_msg("Online CPUs: %d\n", online_cpus);
+	TH_LOG("Online CPUs: %d", online_cpus);
 	if (online_cpus > 16) {
 retry_getslots:
 		futex_slotsn = futex_hash_slots_get();
@@ -200,71 +192,75 @@ TEST(priv_hash)
 			 * sleep for 100ms and issue a futex operation.
 			 */
 			if (retry > 0) {
-				futex_dummy_op();
+				futex_dummy_op(_metadata);
 				goto retry_getslots;
 			}
-			ksft_print_msg("Expected increase of hash buckets but got: %d -> %d\n",
-				       futex_slots1, futex_slotsn);
-			ksft_exit_fail_msg("%s", test_msg_auto_inc);
+			EXPECT_NE(futex_slots1, futex_slotsn)
+				TH_LOG("Expected increase of hash buckets but got: %d -> %d. %s",
+				       futex_slots1, futex_slotsn, test_msg_auto_inc);
 		}
-		ksft_test_result_pass("%s", test_msg_auto_inc);
 	} else {
-		ksft_test_result_skip("%s", test_msg_auto_inc);
+		SKIP(return, "Automatic increase with more than 16 CPUs (only %d online)", online_cpus);
 	}
 	ret = pthread_mutex_unlock(&global_lock);
 
 	/* Once the user changes it, it has to be what is set */
-	futex_hash_slots_set_verify(2);
-	futex_hash_slots_set_verify(4);
-	futex_hash_slots_set_verify(8);
-	futex_hash_slots_set_verify(32);
-	futex_hash_slots_set_verify(16);
+	futex_hash_slots_set_verify(_metadata, 2);
+	futex_hash_slots_set_verify(_metadata, 4);
+	futex_hash_slots_set_verify(_metadata, 8);
+	futex_hash_slots_set_verify(_metadata, 32);
+	futex_hash_slots_set_verify(_metadata, 16);
 
 	ret = futex_hash_slots_set(15);
-	ksft_test_result(ret < 0, "Use 15 slots\n");
+	EXPECT_LT(ret, 0)
+		TH_LOG("Use 15 slots should fail but succeeded");
+
+	futex_hash_slots_set_verify(_metadata, 2);
+	join_max_threads(_metadata);
+
+	EXPECT_EQ(counter, MAX_THREADS)
+		TH_LOG("Created and waited for %d of %d threads", counter, MAX_THREADS);
 
-	futex_hash_slots_set_verify(2);
-	join_max_threads();
-	ksft_test_result(counter == MAX_THREADS, "Created and waited for %d of %d threads\n",
-			 counter, MAX_THREADS);
 	counter = 0;
 	/* Once the user set something, auto resize must be disabled */
 	ret = pthread_barrier_init(&barrier_main, NULL, MAX_THREADS);
+	ASSERT_EQ(ret, 0)
+		TH_LOG("pthread_barrier_init failed: %s", strerror(errno));
 
-	create_max_threads(thread_lock_fn);
-	join_max_threads();
+	create_max_threads(_metadata, thread_lock_fn);
+	join_max_threads(_metadata);
 
 	ret = futex_hash_slots_get();
-	ksft_test_result(ret == 2, "No more auto-resize after manual setting, got %d\n",
-			 ret);
+	EXPECT_EQ(ret, 2)
+		TH_LOG("No more auto-resize after manual setting, got %d", ret);
 
-	futex_hash_slots_set_must_fail(1 << 29);
-	futex_hash_slots_set_verify(4);
+	futex_hash_slots_set_must_fail(_metadata, 1 << 29);
+	futex_hash_slots_set_verify(_metadata, 4);
 
 	/*
 	 * Once the global hash has been requested, then this requested can not
 	 * be undone.
 	 */
 	ret = futex_hash_slots_set(0);
-	ksft_test_result(ret == 0, "Global hash request\n");
-	if (ret != 0)
-		return;
+	ASSERT_EQ(ret, 0)
+		TH_LOG("Global hash request failed: %s", strerror(errno));
 
-	futex_hash_slots_set_must_fail(4);
-	futex_hash_slots_set_must_fail(8);
-	futex_hash_slots_set_must_fail(8);
-	futex_hash_slots_set_must_fail(0);
-	futex_hash_slots_set_must_fail(6);
+	futex_hash_slots_set_must_fail(_metadata, 4);
+	futex_hash_slots_set_must_fail(_metadata, 8);
+	futex_hash_slots_set_must_fail(_metadata, 8);
+	futex_hash_slots_set_must_fail(_metadata, 0);
+	futex_hash_slots_set_must_fail(_metadata, 6);
 
 	ret = pthread_barrier_init(&barrier_main, NULL, MAX_THREADS);
-	if (ret != 0)
-		ksft_exit_fail_msg("pthread_barrier_init failed: %m\n");
+	ASSERT_EQ(ret, 0)
+		TH_LOG("pthread_barrier_init failed: %s", strerror(errno));
 
-	create_max_threads(thread_lock_fn);
-	join_max_threads();
+	create_max_threads(_metadata, thread_lock_fn);
+	join_max_threads(_metadata);
 
 	ret = futex_hash_slots_get();
-	ksft_test_result(ret == 0, "Continue to use global hash\n");
+	EXPECT_EQ(ret, 0)
+		TH_LOG("Continue to use global hash failed");
 }
 
 TEST_HARNESS_MAIN
-- 
2.54.0.823.g6e5bcc1fc9-goog


  parent reply	other threads:[~2026-06-01  6:51 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-01  6:51 [PATCH 0/7] selftests/futex: Migrate requeue, NUMA and robust list tests " Wake Liu
2026-06-01  6:51 ` [PATCH 1/7] selftests/futex: Migrate futex_requeue " Wake Liu
2026-07-05 19:54   ` [tip: locking/futex] " tip-bot2 for Wake Liu
2026-06-01  6:51 ` [PATCH 2/7] selftests/futex: Migrate futex_requeue_pi " Wake Liu
2026-07-05 19:54   ` [tip: locking/futex] " tip-bot2 for Wake Liu
2026-06-01  6:51 ` [PATCH 3/7] selftests/futex: Migrate futex_requeue_pi_mismatched_ops " Wake Liu
2026-07-05 19:54   ` [tip: locking/futex] " tip-bot2 for Wake Liu
2026-06-01  6:51 ` [PATCH 4/7] selftests/futex: Migrate futex_requeue_pi_signal_restart " Wake Liu
2026-07-05 19:54   ` [tip: locking/futex] " tip-bot2 for Wake Liu
2026-06-01  6:51 ` [PATCH 5/7] selftests/futex: Migrate futex_numa_mpol " Wake Liu
2026-07-05 19:54   ` [tip: locking/futex] " tip-bot2 for Wake Liu
2026-06-01  6:51 ` Wake Liu [this message]
2026-07-05 19:54   ` [tip: locking/futex] selftests/futex: Migrate futex_priv_hash " tip-bot2 for Wake Liu
2026-06-01  6:51 ` [PATCH 7/7] selftests/futex: Migrate robust_list " Wake Liu
2026-07-05 19:54   ` [tip: locking/futex] " tip-bot2 for Wake Liu
2026-06-01  8:24 ` [PATCH 0/7] selftests/futex: Migrate requeue, NUMA and robust list tests " Peter Zijlstra
2026-06-03  6:17   ` Wake Liu

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=20260601065126.3623867-7-wakel@google.com \
    --to=wakel@google.com \
    --cc=andrealmeid@igalia.com \
    --cc=cmllamas@google.com \
    --cc=dave@stgolabs.net \
    --cc=dvhart@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=shuah@kernel.org \
    --cc=tglx@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome