From nobody Mon Jun 8 06:36:18 2026 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA32D380FD5 for ; Mon, 1 Jun 2026 06:51:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296696; cv=none; b=bLLaIcmfkfmIMlJokqMwc8MU/5Qba560zU8AYihiLzhsKxpA+BMaNe8ybQ5W0zWjow/iPTvHZ22ZSy1MjYegZFXbPJT6Iv3mH8/AJGeeVt6ejb7J/XdeV5UHMwmSc1C/2wlaA/5nq9SPu0ogCjELF8m/1mE/RW3O7piOB0QrRzQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296696; c=relaxed/simple; bh=x4rgUp/mVj2pfDU22FtK1/2AR5Xxc0PQDdzblyHnxfQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=iNM9CS+KJCKUOwe75vFad+l+g4Ym8c8hkVdiugSfZIdYivcunTqIduTebmLe+gztvxhMm2y9ifJwUpM3xXiIgxfoUcmKQg3tf7YHeW00n8o5uCMMZsIe+J9lTbbhfgUwS6sclXldIGEpVSOjMdGL78rUFdXwIKgduwSGVYwxQ6o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=KF6xLgFI; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="KF6xLgFI" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-842264ce286so1235700b3a.0 for ; Sun, 31 May 2026 23:51:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780296692; x=1780901492; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=6zWjUuiyTvzBfVRhWN5pZV2dCQqAFVFeSqiFeph+2d4=; b=KF6xLgFIT5NOzLeG+ishKxhQXtqU+A3y7f12BS+U20SAgA7Zw7lSrFYcBEksvOUodD M2vgAOvJIC8dRAd2Hwetq3iQ5gKh21u+jS+MKDGhZm9R/ipIPmKNwciKwkRzTX+L8L5N bH84nE+R0t/LTsd7kdcPWFkWWoS8l/AZX8v2ZNRy92VeRmLTd7MZd0vxxazPoG/j2zFQ 6FMCPboNabFdvT1C/KRYHydnM8z2FtAOJv3FkdiicdPPF5y7Nh1+leZlglxEuBluy53P eCbXRHBb9bd4JD+f9ilG7awNAVgMhDbFA1RZTEyRngGkIElFPjlNy6xncaUFnkHBWhhN Y1uA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780296692; x=1780901492; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6zWjUuiyTvzBfVRhWN5pZV2dCQqAFVFeSqiFeph+2d4=; b=U+CI7EnDmmHJwsvPIL7yrs+hztWAkYt1ZQLD5m/sk2JE+5z8Ni5ZTpsLlwaTHCi+zZ ZAGNS8Z49HR5HUQrqWt7LtT40uTR5MmPMIIJpLVRySMGi+2xgwiytB5TdeLHGc9QGL1j YgLWTL7wyDzxSLFBZE1iaev4LtvA4uztzKxmZxvJeOC+PBcsrO3hkRABhwsONNciN2DW rajiuAcU69XCP6A5w7V2Mxvu34h4kHoERvOmYaOhIG/l/qUKfUhlz0K7L9MCM4Mg0q+x GqA8IfnEej1ORltFdJ+2BM6XmChLRGgQZzP4UfXl5j1uuP6rHARotMoYfIhf2b/S7bWs iTNg== X-Forwarded-Encrypted: i=1; AFNElJ9GsJnNX3G9b5eecth0Uur+aJGH3arjL+XJ1GAQH9NniUTeUrFNc4uBENmIeAviM/SjSzTC06ld9bnP9fM=@vger.kernel.org X-Gm-Message-State: AOJu0YwJIgw7RoG+j4mJ/VfT5jnz9V0cv4+HlRzHN560kcAYu/ig7Bfo cGhBR+peG+FY21llKPjFOuLxEduo/ahyeszgNBib28fYp1NtPDU7F0GU0jZZPXYV/Q46HbfbeJP kJw== X-Received: from pfco2.prod.google.com ([2002:a05:6a00:b902:b0:842:492e:19cb]) (user=wakel job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:1ca8:b0:842:4f2d:c4e6 with SMTP id d2e1a72fcca58-8424f2dddeemr2371364b3a.9.1780296691790; Sun, 31 May 2026 23:51:31 -0700 (PDT) Date: Mon, 1 Jun 2026 06:51:20 +0000 In-Reply-To: <20260601065126.3623867-1-wakel@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260601065126.3623867-1-wakel@google.com> X-Mailer: git-send-email 2.54.0.823.g6e5bcc1fc9-goog Message-ID: <20260601065126.3623867-2-wakel@google.com> Subject: [PATCH 1/7] selftests/futex: Migrate futex_requeue to harness From: Wake Liu To: Thomas Gleixner , Ingo Molnar , Shuah Khan , linux-kselftest@vger.kernel.org Cc: Peter Zijlstra , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , Carlos Llamas , linux-kernel@vger.kernel.org, wakel@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Migrate futex_requeue test to the kselftest harness framework, removing mixed legacy ksft_* API usages and ensuring proper thread joining. Signed-off-by: Wake Liu --- .../futex/functional/futex_requeue.c | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_requeue.c b/too= ls/testing/selftests/futex/functional/futex_requeue.c index dcf0d5f2f312..76f0eb6756f8 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue.c +++ b/tools/testing/selftests/futex/functional/futex_requeue.c @@ -7,6 +7,7 @@ =20 #include #include +#include =20 #include "futextest.h" #include "kselftest_harness.h" @@ -18,13 +19,18 @@ volatile futex_t *f1; =20 void *waiterfn(void *arg) { + struct __test_metadata *_metadata =3D (struct __test_metadata *)arg; struct timespec to; + int res; =20 to.tv_sec =3D 0; to.tv_nsec =3D timeout_ns; =20 - if (futex_wait(f1, *f1, &to, 0)) - printf("waiter failed errno %d\n", errno); + res =3D futex_wait(f1, *f1, &to, 0); + if (res) { + EXPECT_EQ(res, 0) + TH_LOG("waiter failed errno %d: %s", errno, strerror(errno)); + } =20 return NULL; } @@ -40,12 +46,15 @@ TEST(requeue_single) /* * Requeue a waiter from f1 to f2, and wake f2. */ - ASSERT_EQ(0, pthread_create(&waiter[0], NULL, waiterfn, NULL)); + ASSERT_EQ(pthread_create(&waiter[0], NULL, waiterfn, _metadata), 0) + TH_LOG("pthread_create failed"); =20 usleep(WAKE_WAIT_US); =20 - EXPECT_EQ(1, futex_cmp_requeue(f1, 0, &f2, 0, 1, 0)); - EXPECT_EQ(1, futex_wake(&f2, 1, 0)); + EXPECT_EQ(futex_cmp_requeue(f1, 0, &f2, 0, 1, 0), 1); + EXPECT_EQ(futex_wake(&f2, 1, 0), 1); + + pthread_join(waiter[0], NULL); } =20 TEST(requeue_multiple) @@ -61,13 +70,18 @@ TEST(requeue_multiple) * Create 10 waiters at f1. At futex_requeue, wake 3 and requeue 7. * At futex_wake, wake INT_MAX (should be exactly 7). */ - for (i =3D 0; i < 10; i++) - ASSERT_EQ(0, pthread_create(&waiter[i], NULL, waiterfn, NULL)); + for (i =3D 0; i < 10; i++) { + ASSERT_EQ(pthread_create(&waiter[i], NULL, waiterfn, _metadata), 0) + TH_LOG("pthread_create failed for waiter %d", i); + } =20 usleep(WAKE_WAIT_US); =20 - EXPECT_EQ(10, futex_cmp_requeue(f1, 0, &f2, 3, 7, 0)); - EXPECT_EQ(7, futex_wake(&f2, INT_MAX, 0)); + EXPECT_EQ(futex_cmp_requeue(f1, 0, &f2, 3, 7, 0), 10); + EXPECT_EQ(futex_wake(&f2, INT_MAX, 0), 7); + + for (i =3D 0; i < 10; i++) + pthread_join(waiter[i], NULL); } =20 TEST_HARNESS_MAIN --=20 2.54.0.823.g6e5bcc1fc9-goog From nobody Mon Jun 8 06:36:18 2026 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC7B2380FDB for ; Mon, 1 Jun 2026 06:51:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296698; cv=none; b=OwagntbH3ECp89zI+NgYLX1ETioCCvKgdLZfg1cyddrEX7UQjL5UGoZLLLMbcFUDelntK/3pieL//YJgdaN6ABlFpXWsPbf6pMe1qxhe1lMfz3h295fqQqTFA/SBS6P8pbunQble9LTLUrbI9ABkBlAG2y3+WOSX7RKPTGX/kHI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296698; c=relaxed/simple; bh=t6U4xgATzs7uG9zfCZMhku4pbFtOXhIM/qDe3guHGbU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=G+0fBeMFHVe1n3m+4yC/opKx+zutd2MUQR5afUgYgUT12ukO+7y8YNXUspdaQZ6AxYVKVPQI+YlooutBPJIPbw5tNFp3nlV6xtxC0hawzBSwVpAXF4SzTujemKdTL36UuZaP5rMVIsI+M+JBo7DBTcatquperKWCFfX/uSlMClA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ZdpVB94m; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ZdpVB94m" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-842211d6e48so2612732b3a.0 for ; Sun, 31 May 2026 23:51:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780296694; x=1780901494; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=uQUuFjhPCX3aGbTJjTXncSLtc0Byk+F869C/pvF6EDk=; b=ZdpVB94mapSDpTb3c/9bgDi9fzKnRBkmaLC3btsk1eYLOE2mriMrKpweY9LNINYCSh zp74N1k+1mTW+UtzTEPmm8b68/ay+mxcaQiSrF0tdXWbcH05mftHWurBp/10V/JlZOK1 BClEhURg4RzvOduJ5VI/Qf3UT/EGJN2LKkquCswiJMfcM4FMDgJhilQeGrNZq8LTbUrS ksN67R6LLC/XIsr7nNCV7M5Z/0l9tGaLUQ8/aM3d+66pVeHec+/YtX1ZhHEhaiDJL8uA /XFi9bRhaVt26uHHkB2tOh2YCKcKnncjzQKquyEViO6i4Y4xbDkn/YNOQ+B7E4HS43Sp lkGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780296694; x=1780901494; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=uQUuFjhPCX3aGbTJjTXncSLtc0Byk+F869C/pvF6EDk=; b=MHBN+78P/bv0F3iGKxKFrT4Bm2prg1rEyahzLICKsH1qVU4w0f+ERLgSbsVyAmVXGn Z/vvqDZDqSL+4uQ0q8SKfdejq73WDte42/fhpi8ukKHwfMkKOcmm88c0VhRDPnoeIECo u0GHgQk9Ba2EB2zjAa5gbv49vAL104Psl1XbMNfAOO8XBLFBjx0ofuqp5olCmCmHz26+ wGknGVOLjYGTExqsnsuuQZoIkkR5NV5tAvHIMFElmXBbjmWCm0+nEi+lL1h2rf6dH6Wk VqcYTfl/dewLXRXRJWCqjp1c1pWjzHiu6JdC1SQWVjCU3QMovS8Z77bD6TEaXAIYfK/C dUSw== X-Forwarded-Encrypted: i=1; AFNElJ95t26jTSvw5mKL/5QH0xO8DGAm5NVm25QLnIKw2k5j7add/xDqPRqRTqlRkeg6dPkwfpC2EVUGPr42568=@vger.kernel.org X-Gm-Message-State: AOJu0YyhFByaLNHm2AB1fkh2ViFgQ5bwVnPVXZXjcbJJpzMhnoWiNY76 6b/bWPo9dhoLlEJm9gu8XhX3xRTDz75aMP+eYd9fvAfbi7hxL5frTnAdlEuV3qnf5GbRr+6FsHN Gsg== X-Received: from pfbk22.prod.google.com ([2002:a05:6a00:b016:b0:842:1f96:2713]) (user=wakel job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:440c:b0:82c:77cd:50e8 with SMTP id d2e1a72fcca58-8422543d835mr9142416b3a.27.1780296693680; Sun, 31 May 2026 23:51:33 -0700 (PDT) Date: Mon, 1 Jun 2026 06:51:21 +0000 In-Reply-To: <20260601065126.3623867-1-wakel@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260601065126.3623867-1-wakel@google.com> X-Mailer: git-send-email 2.54.0.823.g6e5bcc1fc9-goog Message-ID: <20260601065126.3623867-3-wakel@google.com> Subject: [PATCH 2/7] selftests/futex: Migrate futex_requeue_pi to harness From: Wake Liu To: Thomas Gleixner , Ingo Molnar , Shuah Khan , linux-kselftest@vger.kernel.org Cc: Peter Zijlstra , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , Carlos Llamas , linux-kernel@vger.kernel.org, wakel@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Migrate futex_requeue_pi test to the kselftest harness framework, removing mixed legacy ksft_* API usages and passing test metadata to all helper threads via thread arguments. Signed-off-by: Wake Liu --- .../futex/functional/futex_requeue_pi.c | 130 +++++++++--------- 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi.c b/= tools/testing/selftests/futex/functional/futex_requeue_pi.c index 46d2858e15a8..11aada818068 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue_pi.c +++ b/tools/testing/selftests/futex/functional/futex_requeue_pi.c @@ -43,12 +43,13 @@ futex_t f2 =3D FUTEX_INITIALIZER; futex_t wake_complete =3D FUTEX_INITIALIZER; =20 struct thread_arg { + struct __test_metadata *_metadata; long id; struct timespec *timeout; int lock; int ret; }; -#define THREAD_ARG_INITIALIZER { 0, NULL, 0, 0 } +#define THREAD_ARG_INITIALIZER { NULL, 0, NULL, 0, 0 } =20 FIXTURE(args) { @@ -118,7 +119,7 @@ FIXTURE_VARIANT_ADD_TIMEOUT(5000); FIXTURE_VARIANT_ADD_TIMEOUT(500000); FIXTURE_VARIANT_ADD_TIMEOUT(2000000000); =20 -int create_rt_thread(pthread_t *pth, void*(*func)(void *), void *arg, +int create_rt_thread(struct __test_metadata *_metadata, pthread_t *pth, vo= id*(*func)(void *), void *arg, int policy, int prio) { int ret; @@ -129,29 +130,18 @@ int create_rt_thread(pthread_t *pth, void*(*func)(voi= d *), void *arg, memset(&schedp, 0, sizeof(schedp)); =20 ret =3D pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); - if (ret) { - ksft_exit_fail_msg("pthread_attr_setinheritsched\n"); - return -1; - } + ASSERT_EQ(ret, 0) TH_LOG("pthread_attr_setinheritsched failed"); =20 ret =3D pthread_attr_setschedpolicy(&attr, policy); - if (ret) { - ksft_exit_fail_msg("pthread_attr_setschedpolicy\n"); - return -1; - } + ASSERT_EQ(ret, 0) TH_LOG("pthread_attr_setschedpolicy failed"); =20 schedp.sched_priority =3D prio; ret =3D pthread_attr_setschedparam(&attr, &schedp); - if (ret) { - ksft_exit_fail_msg("pthread_attr_setschedparam\n"); - return -1; - } + ASSERT_EQ(ret, 0) TH_LOG("pthread_attr_setschedparam failed"); =20 ret =3D pthread_create(pth, &attr, func, arg); - if (ret) { - ksft_exit_fail_msg("pthread_create\n"); - return -1; - } + ASSERT_EQ(ret, 0) TH_LOG("pthread_create failed"); + return 0; } =20 @@ -159,55 +149,59 @@ int create_rt_thread(pthread_t *pth, void*(*func)(voi= d *), void *arg, void *waiterfn(void *arg) { struct thread_arg *args =3D (struct thread_arg *)arg; + struct __test_metadata *_metadata =3D args->_metadata; futex_t old_val; =20 - ksft_print_dbg_msg("Waiter %ld: running\n", args->id); + TH_LOG("Waiter %ld: running", args->id); /* Each thread sleeps for a different amount of time * This is to avoid races, because we don't lock the - * external mutex here */ + * external mutex here + */ usleep(1000 * (long)args->id); =20 old_val =3D f1; atomic_inc(&waiters_blocked); - ksft_print_dbg_msg("Calling futex_wait_requeue_pi: %p (%u) -> %p\n", + TH_LOG("Calling futex_wait_requeue_pi: %p (%u) -> %p", &f1, f1, &f2); args->ret =3D futex_wait_requeue_pi(&f1, old_val, &f2, args->timeout, FUTEX_PRIVATE_FLAG); =20 - ksft_print_dbg_msg("waiter %ld woke with %d %s\n", args->id, args->ret, + TH_LOG("waiter %ld woke with %d %s", args->id, args->ret, args->ret < 0 ? strerror(errno) : ""); atomic_inc(&waiters_woken); if (args->ret < 0) { - if (args->timeout && errno =3D=3D ETIMEDOUT) + if (args->timeout && errno =3D=3D ETIMEDOUT) { args->ret =3D 0; - else { - ksft_exit_fail_msg("futex_wait_requeue_pi\n"); + } else { + ASSERT_EQ(args->ret, 0) + TH_LOG("futex_wait_requeue_pi failed: %s", strerror(errno)); } futex_lock_pi(&f2, NULL, 0, FUTEX_PRIVATE_FLAG); } futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG); =20 - ksft_print_dbg_msg("Waiter %ld: exiting with %d\n", args->id, args->ret); + TH_LOG("Waiter %ld: exiting with %d", args->id, args->ret); pthread_exit((void *)&args->ret); } =20 void *broadcast_wakerfn(void *arg) { struct thread_arg *args =3D (struct thread_arg *)arg; + struct __test_metadata *_metadata =3D args->_metadata; int nr_requeue =3D INT_MAX; int task_count =3D 0; futex_t old_val; int nr_wake =3D 1; int i =3D 0; =20 - ksft_print_dbg_msg("Waker: waiting for waiters to block\n"); + TH_LOG("Waker: waiting for waiters to block"); while (waiters_blocked.val < THREAD_MAX) usleep(1000); usleep(1000); =20 - ksft_print_dbg_msg("Waker: Calling broadcast\n"); + TH_LOG("Waker: Calling broadcast"); if (args->lock) { - ksft_print_dbg_msg("Calling FUTEX_LOCK_PI on mutex=3D%x @ %p\n", f2, &f2= ); + TH_LOG("Calling FUTEX_LOCK_PI on mutex=3D%x @ %p", f2, &f2); futex_lock_pi(&f2, NULL, 0, FUTEX_PRIVATE_FLAG); } continue_requeue: @@ -215,14 +209,16 @@ void *broadcast_wakerfn(void *arg) args->ret =3D futex_cmp_requeue_pi(&f1, old_val, &f2, nr_wake, nr_requeue, FUTEX_PRIVATE_FLAG); if (args->ret < 0) { - ksft_exit_fail_msg("FUTEX_CMP_REQUEUE_PI failed\n"); + ASSERT_GE(args->ret, 0) + TH_LOG("FUTEX_CMP_REQUEUE_PI failed: %s", strerror(errno)); } else if (++i < MAX_WAKE_ITERS) { task_count +=3D args->ret; if (task_count < THREAD_MAX - waiters_woken.val) goto continue_requeue; } else { - ksft_exit_fail_msg("max broadcast iterations (%d) reached with %d/%d tas= ks woken or requeued\n", - MAX_WAKE_ITERS, task_count, THREAD_MAX); + ASSERT_TRUE(0) + TH_LOG("max broadcast iterations (%d) reached with %d/%d tasks woken or= requeued", + MAX_WAKE_ITERS, task_count, THREAD_MAX); } =20 futex_wake(&wake_complete, 1, FUTEX_PRIVATE_FLAG); @@ -233,33 +229,34 @@ void *broadcast_wakerfn(void *arg) if (args->ret > 0) args->ret =3D task_count; =20 - ksft_print_dbg_msg("Waker: exiting with %d\n", args->ret); + TH_LOG("Waker: exiting with %d", args->ret); pthread_exit((void *)&args->ret); } =20 void *signal_wakerfn(void *arg) { struct thread_arg *args =3D (struct thread_arg *)arg; + struct __test_metadata *_metadata =3D args->_metadata; unsigned int old_val; int nr_requeue =3D 0; int task_count =3D 0; int nr_wake =3D 1; int i =3D 0; =20 - ksft_print_dbg_msg("Waker: waiting for waiters to block\n"); + TH_LOG("Waker: waiting for waiters to block"); while (waiters_blocked.val < THREAD_MAX) usleep(1000); usleep(1000); =20 while (task_count < THREAD_MAX && waiters_woken.val < THREAD_MAX) { - ksft_print_dbg_msg("task_count: %d, waiters_woken: %d\n", + TH_LOG("task_count: %d, waiters_woken: %d", task_count, waiters_woken.val); if (args->lock) { - ksft_print_dbg_msg("Calling FUTEX_LOCK_PI on mutex=3D%x @ %p\n", + TH_LOG("Calling FUTEX_LOCK_PI on mutex=3D%x @ %p", f2, &f2); futex_lock_pi(&f2, NULL, 0, FUTEX_PRIVATE_FLAG); } - ksft_print_dbg_msg("Waker: Calling signal\n"); + TH_LOG("Waker: Calling signal"); /* cond_signal */ old_val =3D f1; args->ret =3D futex_cmp_requeue_pi(&f1, old_val, &f2, @@ -267,23 +264,26 @@ void *signal_wakerfn(void *arg) FUTEX_PRIVATE_FLAG); if (args->ret < 0) args->ret =3D -errno; - ksft_print_dbg_msg("futex: %x\n", f2); + TH_LOG("futex: %x", f2); if (args->lock) { - ksft_print_dbg_msg("Calling FUTEX_UNLOCK_PI on mutex=3D%x @ %p\n", + TH_LOG("Calling FUTEX_UNLOCK_PI on mutex=3D%x @ %p", f2, &f2); futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG); } - ksft_print_dbg_msg("futex: %x\n", f2); - if (args->ret < 0) - ksft_exit_fail_msg("FUTEX_CMP_REQUEUE_PI failed\n"); + TH_LOG("futex: %x", f2); + if (args->ret < 0) { + ASSERT_GE(args->ret, 0) + TH_LOG("FUTEX_CMP_REQUEUE_PI failed: %s", strerror(-args->ret)); + } =20 task_count +=3D args->ret; usleep(SIGNAL_PERIOD_US); i++; /* we have to loop at least THREAD_MAX times */ if (i > MAX_WAKE_ITERS + THREAD_MAX) { - ksft_exit_fail_msg("max signaling iterations (%d) reached, giving up on= pending waiters.\n", - MAX_WAKE_ITERS + THREAD_MAX); + ASSERT_TRUE(0) + TH_LOG("max signaling iterations (%d) reached, giving up on pending wa= iters.", + MAX_WAKE_ITERS + THREAD_MAX); } } =20 @@ -292,14 +292,15 @@ void *signal_wakerfn(void *arg) if (args->ret >=3D 0) args->ret =3D task_count; =20 - ksft_print_dbg_msg("Waker: exiting with %d\n", args->ret); - ksft_print_dbg_msg("Waker: waiters_woken: %d\n", waiters_woken.val); + TH_LOG("Waker: exiting with %d", args->ret); + TH_LOG("Waker: waiters_woken: %d", waiters_woken.val); pthread_exit((void *)&args->ret); } =20 void *third_party_blocker(void *arg) { struct thread_arg *args =3D (struct thread_arg *)arg; + struct __test_metadata *_metadata =3D args->_metadata; int ret2 =3D 0; =20 args->ret =3D futex_lock_pi(&f2, NULL, 0, FUTEX_PRIVATE_FLAG); @@ -311,7 +312,7 @@ void *third_party_blocker(void *arg) =20 out: if (args->ret || ret2) - ksft_exit_fail_msg("third_party_blocker() futex error"); + ASSERT_TRUE(0) TH_LOG("%s() futex error", __func__); =20 pthread_exit((void *)&args->ret); } @@ -330,20 +331,19 @@ TEST_F(args, futex_requeue_pi) bool lock =3D variant->locked; int *waiter_ret, i, ret =3D 0; =20 - ksft_print_msg( - "\tArguments: broadcast=3D%d locked=3D%d owner=3D%d timeout=3D%ldns\n", + TH_LOG("Arguments: broadcast=3D%d locked=3D%d owner=3D%d timeout=3D%ldns", broadcast, lock, third_party_owner, timeout_ns); =20 if (timeout_ns) { time_t secs; =20 - ksft_print_dbg_msg("timeout_ns =3D %ld\n", timeout_ns); + TH_LOG("timeout_ns =3D %ld", timeout_ns); ret =3D clock_gettime(CLOCK_MONOTONIC, &ts); secs =3D (ts.tv_nsec + timeout_ns) / 1000000000; ts.tv_nsec =3D ((int64_t)ts.tv_nsec + timeout_ns) % 1000000000; ts.tv_sec +=3D secs; - ksft_print_dbg_msg("ts.tv_sec =3D %ld\n", ts.tv_sec); - ksft_print_dbg_msg("ts.tv_nsec =3D %ld\n", ts.tv_nsec); + TH_LOG("ts.tv_sec =3D %ld", ts.tv_sec); + TH_LOG("ts.tv_nsec =3D %ld", ts.tv_nsec); tsp =3D &ts; } =20 @@ -351,27 +351,24 @@ TEST_F(args, futex_requeue_pi) wakerfn =3D broadcast_wakerfn; =20 if (third_party_owner) { - if (create_rt_thread(&blocker, third_party_blocker, - (void *)&blocker_arg, SCHED_FIFO, 1)) { - ksft_exit_fail_msg("Creating third party blocker thread failed\n"); - } + blocker_arg._metadata =3D _metadata; + create_rt_thread(_metadata, &blocker, third_party_blocker, + (void *)&blocker_arg, SCHED_FIFO, 1); } =20 atomic_set(&waiters_woken, 0); for (i =3D 0; i < THREAD_MAX; i++) { + args[i]._metadata =3D _metadata; args[i].id =3D i; args[i].timeout =3D tsp; - ksft_print_dbg_msg("Starting thread %d\n", i); - if (create_rt_thread(&waiter[i], waiterfn, (void *)&args[i], - SCHED_FIFO, 1)) { - ksft_exit_fail_msg("Creating waiting thread failed\n"); - } + TH_LOG("Starting thread %d", i); + create_rt_thread(_metadata, &waiter[i], waiterfn, (void *)&args[i], + SCHED_FIFO, 1); } + waker_arg._metadata =3D _metadata; waker_arg.lock =3D lock; - if (create_rt_thread(&waker, wakerfn, (void *)&waker_arg, - SCHED_FIFO, 1)) { - ksft_exit_fail_msg("Creating waker thread failed\n"); - } + create_rt_thread(_metadata, &waker, wakerfn, (void *)&waker_arg, + SCHED_FIFO, 1); =20 /* Wait for threads to finish */ /* Store the first error or failure encountered in waiter_ret */ @@ -393,8 +390,7 @@ TEST_F(args, futex_requeue_pi) ret =3D blocker_arg.ret; } =20 - if (ret) - ksft_test_result_fail("fail"); + EXPECT_EQ(ret, 0) TH_LOG("Test failed with error code: %d", ret); } =20 TEST_HARNESS_MAIN --=20 2.54.0.823.g6e5bcc1fc9-goog From nobody Mon Jun 8 06:36:18 2026 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D7FE9380FDF for ; Mon, 1 Jun 2026 06:51:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296699; cv=none; b=Mzxn/Qxnv7gqvYfgoTEeM5ApFi0CjeIkyA73X0/5cIF+JYq9SQs41833HrzIveKJKZm8h16Lio5vW6nOY+lqAvwxeKEc209oDzUrm+CWhdOHlCVWPl8hrLVoeGIldvsaBfbVCpXsq6uqNh8W4AykLpJm/O3JvVW4XIlRqq6Ee/o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296699; c=relaxed/simple; bh=zQyElqJggpdAoRCfqjPth8BzP2CEJO+096dvpyMO/58=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=HYgZG9CJBxHS/8uqjsnS+IkTS44UPWw22RH8GQTrXcG+Z8HtpE6hnT+4mFDDILmbFKqPCyJy2aB/F7LwXTomVCab1hSDvxyjMzyYXg4gqVoXteGKaS5G5hvG9jaZV0pn0n80EMcPAKC3V8/PLV2slPQaSi06OC64mFdcwuZ3QcA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=u9gNx47r; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="u9gNx47r" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-842278a630dso2520327b3a.2 for ; Sun, 31 May 2026 23:51:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780296696; x=1780901496; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=1hNLATkHbi9kvgAQrnw7X+32QULnpyW2fwEQdl2tOKs=; b=u9gNx47rgs+cOMCbfZhaLasmWvP3V9hNxDa1zF5pSB/8ABVHgNEEF8jLURpGyV/TYB RKyW/v9KVndwUDWoacszTForcQmkgfC+JwNbPhK6UyyAA0AX7cH1fKtAY3OFhP0JxVtv kYw9OBjgH9J3Bj3Q8C9Iwhk8SeAy4A5PXxZtw534gHhrfcPFrQDy3ej8CMS6ltC68coc vwwVfZy+F+JXTNPQdquBvbH7XZeYjzYykBPOYWZ0u3bo7CvkVysq9vyIYowx0bQcKcWL OcdQHMJbdvTcYuJY7eWdG5g5dTpAizFYGhI5JqUj7CM3htvdeJiy9X/Pji+joyIVXJ1a FBVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780296696; x=1780901496; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=1hNLATkHbi9kvgAQrnw7X+32QULnpyW2fwEQdl2tOKs=; b=rG2b1Zn7JyZ5jhUkAnpftm+o0/9zm59b2fv4jyNM1mkiJvB0erxip0Q4BDT4bnA5/i yepnBxb3mrIQoAuzuK0TQrvDY2u0gpsszpABrqiMO/EynljQxY6v0PKpBJ+dspz0l92M DX0DL/6vj1CTvRXXEprlkPfhH8EHl22ewIzKu2ewJCAKZ3X+d3aHRRN32VJ2b+LXeDUa 2ZmAtbeChKqRZQUJUFZ5FgVJ+Fy+wQVdYMFH2eVDfa8GF2SMU2qai7BBY5bRFUhDBeFl cKrVVs2JIso38+3JVfiNFVR/8pRfcRKojawSkjxubAdwGq+6HzMYxKi2KrsygDT2Ynj1 wtRQ== X-Forwarded-Encrypted: i=1; AFNElJ+ulex9pper8NOdpae4a+bz+rsQkA9Ec8FxovFMsHpoOrZ+83OvHbWiYhZpDhQdBr2D8/EzzV9FFDiO02Y=@vger.kernel.org X-Gm-Message-State: AOJu0YwTzV73Cgoi/m3ImLT36d0jIKpcA0zkUuwK00RWADTcMRByjpas LinJLXz3A7LMsshd6GdDbEKrRDnG7lgaYaQqE2Zs5XWcyi0MMz6Xs2HD+oAtejJWPnS4487vxGW 7vA== X-Received: from pfbmu27.prod.google.com ([2002:a05:6a00:6e9b:b0:842:414c:de5f]) (user=wakel job=prod-delivery.src-stubby-dispatcher) by 2002:aa7:9a8c:0:b0:83d:b0a0:90e3 with SMTP id d2e1a72fcca58-84225478823mr8881984b3a.31.1780296695741; Sun, 31 May 2026 23:51:35 -0700 (PDT) Date: Mon, 1 Jun 2026 06:51:22 +0000 In-Reply-To: <20260601065126.3623867-1-wakel@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260601065126.3623867-1-wakel@google.com> X-Mailer: git-send-email 2.54.0.823.g6e5bcc1fc9-goog Message-ID: <20260601065126.3623867-4-wakel@google.com> Subject: [PATCH 3/7] selftests/futex: Migrate futex_requeue_pi_mismatched_ops to harness From: Wake Liu To: Thomas Gleixner , Ingo Molnar , Shuah Khan , linux-kselftest@vger.kernel.org Cc: Peter Zijlstra , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , Carlos Llamas , linux-kernel@vger.kernel.org, wakel@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Migrate futex_requeue_pi_mismatched_ops test to the kselftest harness frame= work, removing mixed legacy ksft_* API usages and passing test metadata to helper= thread. Signed-off-by: Wake Liu --- .../futex_requeue_pi_mismatched_ops.c | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi_mism= atched_ops.c b/tools/testing/selftests/futex/functional/futex_requeue_pi_mi= smatched_ops.c index f686e605359c..c55eadd261da 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_= ops.c +++ b/tools/testing/selftests/futex/functional/futex_requeue_pi_mismatched_= ops.c @@ -29,14 +29,17 @@ =20 futex_t f1 =3D FUTEX_INITIALIZER; futex_t f2 =3D FUTEX_INITIALIZER; -int child_ret =3D 0; +int child_ret; =20 void *blocking_child(void *arg) { + struct __test_metadata *_metadata =3D (struct __test_metadata *)arg; + child_ret =3D futex_wait(&f1, f1, NULL, FUTEX_PRIVATE_FLAG); if (child_ret < 0) { child_ret =3D -errno; - ksft_exit_fail_msg("futex_wait\n"); + ASSERT_EQ(child_ret, 0) + TH_LOG("futex_wait failed: %s", strerror(errno)); } return (void *)&child_ret; } @@ -46,8 +49,8 @@ TEST(requeue_pi_mismatched_ops) pthread_t child; int ret; =20 - if (pthread_create(&child, NULL, blocking_child, NULL)) - ksft_exit_fail_msg("pthread_create\n"); + ASSERT_EQ(pthread_create(&child, NULL, blocking_child, _metadata), 0) + TH_LOG("pthread_create failed"); =20 /* Allow the child to block in the kernel. */ sleep(1); @@ -67,27 +70,31 @@ TEST(requeue_pi_mismatched_ops) * FUTEX_WAKE. */ ret =3D futex_wake(&f1, 1, FUTEX_PRIVATE_FLAG); - if (ret =3D=3D 1) + if (ret =3D=3D 1) { ret =3D 0; - else if (ret < 0) - ksft_exit_fail_msg("futex_wake\n"); - else - ksft_exit_fail_msg("futex_wake did not wake the child\n"); + } else if (ret < 0) { + ASSERT_GE(ret, 0) + TH_LOG("futex_wake failed: %s", strerror(errno)); + } else { + ASSERT_TRUE(0) + TH_LOG("futex_wake did not wake the child"); + } } else { - ksft_exit_fail_msg("futex_cmp_requeue_pi\n"); + ASSERT_TRUE(0) + TH_LOG("futex_cmp_requeue_pi failed with unexpected errno: %s", strerr= or(errno)); } } else if (ret > 0) { - ksft_test_result_fail("futex_cmp_requeue_pi failed to detect the mismatc= h\n"); + EXPECT_EQ(ret, 0) + TH_LOG("futex_cmp_requeue_pi failed to detect the mismatch"); } else { - ksft_exit_fail_msg("futex_cmp_requeue_pi found no waiters\n"); + ASSERT_TRUE(0) + TH_LOG("futex_cmp_requeue_pi found no waiters"); } =20 pthread_join(child, NULL); =20 - if (!ret && !child_ret) - ksft_test_result_pass("futex_requeue_pi_mismatched_ops passed\n"); - else - ksft_test_result_pass("futex_requeue_pi_mismatched_ops failed\n"); + EXPECT_EQ(ret, 0) TH_LOG("Test failed: ret=3D%d", ret); + EXPECT_EQ(child_ret, 0) TH_LOG("Child failed: child_ret=3D%d", child_ret); } =20 TEST_HARNESS_MAIN --=20 2.54.0.823.g6e5bcc1fc9-goog From nobody Mon Jun 8 06:36:18 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA9E83803D6 for ; Mon, 1 Jun 2026 06:51:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296702; cv=none; b=EBACzOBYkDoaiUAPCpbZwlRKiziNxtQfdMQlgOClBmKkhOK/JXyle7h0Os5Mzlh9IPX3ffP10hntg9L1cdyr8dnx1CsxSBV2aTkeX35BzC9hkRpBCuHY6LZa2n2s/2Xsbh8toygWoVTv37kNO8oVV8tuILZWEKoxgeDfbzrXbjg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296702; c=relaxed/simple; bh=ABYUNeq5jggGjdHC1N3KhsSD1Eg+ZJUhKBpwrvEvOUg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fvU77Ik5nEdoIoRbHI2k3i9Ay0Vt3rK3ye/Pw6UBFmfVUcLEKl9en/bw2yAP5uzTNwmxB1xBJQ3ZLJjEoo54Hs70pXDdxrD5I5OPkYdj8BfdT0oDE95vMWl8yNp9fFnY80hJ2BLQsKjHDiQ0vNq65A//ozk9Mciw43KGlmrDWns= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=s0cnTx90; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="s0cnTx90" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-c85a2cde332so525092a12.3 for ; Sun, 31 May 2026 23:51:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780296698; x=1780901498; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=b8X/ZMOC3R4zjF20OsNMGuI7f1VgwjsLyl+ryXVYUmA=; b=s0cnTx90wrkqbuZnDDxRKzFeE3NxVCVIQX4STfYgTQkLGGC4ylet1nkp/G557KbSIg /rpghqFAYsdjFF4/8hfSrW+T31glYnZ489cX4j4HuS4iyokZc1qfFG525G+cogdGy+O7 qNsLHNKZe6nIC2SC1xgIWI3ktScnX48Nf7vU82ojMX2BDthNr8rdxhUDu8v0jU9nM4YL kGBIsBNjg6drgofNeeNhVd1CKQ8ZdcFeP7k2p7mqafKBinGYGXHYH99qRG+VEPppvPvw iw8lj7V5SJj0dnJnBdMuKPLAPdjGvpKmXIJLjhAtQWvup9Ov/9r2DWswycmgtqfmTGei JC0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780296698; x=1780901498; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=b8X/ZMOC3R4zjF20OsNMGuI7f1VgwjsLyl+ryXVYUmA=; b=ZaBagcNekt6KOy1PQ3i5cyG/fpILpjIdHF3tf1/8TK4Zk+Np7vmyhqc3IcWTBc0R+9 cncQ6LGyeY00fQmURORu1vQca9iKizRm9CzjmvJfIyKBGMI7RDdy6VHZnqGnGstIg51/ IgnlrjJn5xiwG0bIqL01qgTozMAxlsFHZq6tRCQNm1tOvLsKcfOh8luXIiGdLaoPnBaG oOc0GETLifp8lqSYgFpgBuCG1XCADRq5fchexwXiEkzWF6e8DXLbcU5sqm0QBgb7CRpH uEkSz8ygo7g4whlL3Qcm0wU5KXwbSRxj7xcPqnLRyljy86HiAmOkWznj3izD0uf/qXDe owFA== X-Forwarded-Encrypted: i=1; AFNElJ9K9LVjTUnDJQIXJsDEN+qPObeq4xAeA3vPuiMxU9gonSXna25PEx6nDYZDgklKyH9/UrydHHbY0s1UQf0=@vger.kernel.org X-Gm-Message-State: AOJu0YxZjoJIflfzt2IbM9nt81itjazryPnz++WD9OJQEndMxOMKCBQF NQFgtTAjeEKcugsOw59ze0PEa+1lsqe19nUMkbA3ETT1Betihn1mrlhf2igEqmHBSuCgOaNhCuP nFQ== X-Received: from pgbdw17.prod.google.com ([2002:a05:6a02:4491:b0:c0e:3543:bdb0]) (user=wakel job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:6497:b0:3a2:dabf:fef6 with SMTP id adf61e73a8af0-3b427f5b066mr9976790637.35.1780296697723; Sun, 31 May 2026 23:51:37 -0700 (PDT) Date: Mon, 1 Jun 2026 06:51:23 +0000 In-Reply-To: <20260601065126.3623867-1-wakel@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260601065126.3623867-1-wakel@google.com> X-Mailer: git-send-email 2.54.0.823.g6e5bcc1fc9-goog Message-ID: <20260601065126.3623867-5-wakel@google.com> Subject: [PATCH 4/7] selftests/futex: Migrate futex_requeue_pi_signal_restart to harness From: Wake Liu To: Thomas Gleixner , Ingo Molnar , Shuah Khan , linux-kselftest@vger.kernel.org Cc: Peter Zijlstra , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , Carlos Llamas , linux-kernel@vger.kernel.org, wakel@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Migrate futex_requeue_pi_signal_restart test to the kselftest harness frame= work, removing mixed legacy ksft_* API usages and ensuring proper thread joining. Signed-off-by: Wake Liu --- .../futex_requeue_pi_signal_restart.c | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_requeue_pi_sign= al_restart.c b/tools/testing/selftests/futex/functional/futex_requeue_pi_si= gnal_restart.c index a18ccae73eb1..e301beb4b202 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_rest= art.c +++ b/tools/testing/selftests/futex/functional/futex_requeue_pi_signal_rest= art.c @@ -35,9 +35,9 @@ futex_t f1 =3D FUTEX_INITIALIZER; futex_t f2 =3D FUTEX_INITIALIZER; atomic_t requeued =3D ATOMIC_INITIALIZER; =20 -int waiter_ret =3D 0; +int waiter_ret; =20 -int create_rt_thread(pthread_t *pth, void*(*func)(void *), void *arg, +int create_rt_thread(struct __test_metadata *_metadata, pthread_t *pth, vo= id*(*func)(void *), void *arg, int policy, int prio) { struct sched_param schedp; @@ -48,45 +48,43 @@ int create_rt_thread(pthread_t *pth, void*(*func)(void = *), void *arg, memset(&schedp, 0, sizeof(schedp)); =20 ret =3D pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); - if (ret) - ksft_exit_fail_msg("pthread_attr_setinheritsched\n"); + ASSERT_EQ(ret, 0) TH_LOG("pthread_attr_setinheritsched failed"); =20 ret =3D pthread_attr_setschedpolicy(&attr, policy); - if (ret) - ksft_exit_fail_msg("pthread_attr_setschedpolicy\n"); + ASSERT_EQ(ret, 0) TH_LOG("pthread_attr_setschedpolicy failed"); =20 schedp.sched_priority =3D prio; ret =3D pthread_attr_setschedparam(&attr, &schedp); - if (ret) - ksft_exit_fail_msg("pthread_attr_setschedparam\n"); + ASSERT_EQ(ret, 0) TH_LOG("pthread_attr_setschedparam failed"); =20 ret =3D pthread_create(pth, &attr, func, arg); - if (ret) - ksft_exit_fail_msg("pthread_create\n"); + ASSERT_EQ(ret, 0) TH_LOG("pthread_create failed"); =20 return 0; } =20 void handle_signal(int signo) { - ksft_print_dbg_msg("signal received %s requeue\n", - requeued.val ? "after" : "prior to"); + printf("INFO: signal received %s requeue\n", + requeued.val ? "after" : "prior to"); } =20 void *waiterfn(void *arg) { + struct __test_metadata *_metadata =3D (struct __test_metadata *)arg; unsigned int old_val; int res; =20 - ksft_print_dbg_msg("Waiter running\n"); - ksft_print_dbg_msg("Calling FUTEX_LOCK_PI on f2=3D%x @ %p\n", f2, &f2); + TH_LOG("Waiter running"); + TH_LOG("Calling FUTEX_LOCK_PI on f2=3D%x @ %p", f2, &f2); old_val =3D f1; res =3D futex_wait_requeue_pi(&f1, old_val, &(f2), NULL, FUTEX_PRIVATE_FLAG); if (!requeued.val || errno !=3D EWOULDBLOCK) { - ksft_test_result_fail("unexpected return from futex_wait_requeue_pi: %d = (%s)\n", - res, strerror(errno)); - ksft_print_dbg_msg("w2:futex: %x\n", f2); + EXPECT_TRUE(0) + TH_LOG("unexpected return from futex_wait_requeue_pi: %d (%s)", + res, strerror(errno)); + TH_LOG("w2:futex: %x", f2); if (!res) futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG); } @@ -94,7 +92,6 @@ void *waiterfn(void *arg) pthread_exit(NULL); } =20 - TEST(futex_requeue_pi_signal_restart) { unsigned int old_val; @@ -105,19 +102,16 @@ TEST(futex_requeue_pi_signal_restart) sa.sa_handler =3D handle_signal; sigemptyset(&sa.sa_mask); sa.sa_flags =3D 0; - if (sigaction(SIGUSR1, &sa, NULL)) - ksft_exit_fail_msg("sigaction\n"); + ASSERT_EQ(sigaction(SIGUSR1, &sa, NULL), 0) TH_LOG("sigaction failed"); =20 - ksft_print_dbg_msg("m1:f2: %x\n", f2); - ksft_print_dbg_msg("Creating waiter\n"); - res =3D create_rt_thread(&waiter, waiterfn, NULL, SCHED_FIFO, 1); - if (res) - ksft_exit_fail_msg("Creating waiting thread failed"); + TH_LOG("m1:f2: %x", f2); + TH_LOG("Creating waiter"); + create_rt_thread(_metadata, &waiter, waiterfn, _metadata, SCHED_FIFO, 1); =20 - ksft_print_dbg_msg("Calling FUTEX_LOCK_PI on f2=3D%x @ %p\n", f2, &f2); - ksft_print_dbg_msg("m2:f2: %x\n", f2); + TH_LOG("Calling FUTEX_LOCK_PI on f2=3D%x @ %p", f2, &f2); + TH_LOG("m2:f2: %x", f2); futex_lock_pi(&f2, 0, 0, FUTEX_PRIVATE_FLAG); - ksft_print_dbg_msg("m3:f2: %x\n", f2); + TH_LOG("m3:f2: %x", f2); =20 while (1) { /* @@ -125,11 +119,11 @@ TEST(futex_requeue_pi_signal_restart) * restart futex_wait_requeue_pi() in the kernel. Wait for the * waiter to block on f1 again. */ - ksft_print_dbg_msg("Issuing SIGUSR1 to waiter\n"); + TH_LOG("Issuing SIGUSR1 to waiter"); pthread_kill(waiter, SIGUSR1); usleep(DELAY_US); =20 - ksft_print_dbg_msg("Requeueing waiter via FUTEX_CMP_REQUEUE_PI\n"); + TH_LOG("Requeueing waiter via FUTEX_CMP_REQUEUE_PI"); old_val =3D f1; res =3D futex_cmp_requeue_pi(&f1, old_val, &(f2), 1, 0, FUTEX_PRIVATE_FLAG); @@ -143,10 +137,11 @@ TEST(futex_requeue_pi_signal_restart) atomic_set(&requeued, 1); break; } else if (res < 0) { - ksft_exit_fail_msg("FUTEX_CMP_REQUEUE_PI failed\n"); + ASSERT_GE(res, 0) + TH_LOG("FUTEX_CMP_REQUEUE_PI failed: %s", strerror(errno)); } } - ksft_print_dbg_msg("m4:f2: %x\n", f2); + TH_LOG("m4:f2: %x", f2); =20 /* * Signal the waiter after requeue, waiter should return from @@ -154,14 +149,14 @@ TEST(futex_requeue_pi_signal_restart) * futex_unlock_pi() can't happen before the signal wakeup is detected * in the kernel. */ - ksft_print_dbg_msg("Issuing SIGUSR1 to waiter\n"); + TH_LOG("Issuing SIGUSR1 to waiter"); pthread_kill(waiter, SIGUSR1); - ksft_print_dbg_msg("Waiting for waiter to return\n"); + TH_LOG("Waiting for waiter to return"); pthread_join(waiter, NULL); =20 - ksft_print_dbg_msg("Calling FUTEX_UNLOCK_PI on mutex=3D%x @ %p\n", f2, &f= 2); + TH_LOG("Calling FUTEX_UNLOCK_PI on mutex=3D%x @ %p", f2, &f2); futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG); - ksft_print_dbg_msg("m5:f2: %x\n", f2); + TH_LOG("m5:f2: %x", f2); } =20 TEST_HARNESS_MAIN --=20 2.54.0.823.g6e5bcc1fc9-goog From nobody Mon Jun 8 06:36:18 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DBEC5382380 for ; Mon, 1 Jun 2026 06:51:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296705; cv=none; b=N/N7Ga2rlZSV6tCn0UdugzknccIATj7fE8ZRD31/7Jqj3dn+uJE/clf5GWW83bSZ2k3YC69+HQ9gD4C+cUpctbeVgD9iyvDoT/47riZY7ZciNtcHeTd0R8plrh4+wkzGShMZ0hO/8N3yzEuy1tHwpuhJYGzV2SzuyiatoOVj2FU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296705; c=relaxed/simple; bh=RhbZjldDEvRmcXRUgBq8zs621qLiWWhWxGM9YPdTZFU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PRmmwm7o4zC/V6+kwItBFgEXWQKOEGcJirCplruWhVWhCNT0zfKI18Etfihe00rbdIrtJpP/x70Ew7dkKQGwV5LIif5nWgFtmkEFbiW/YHpV/CpWSN9CJq0oGZU7GobYOHJNEAxHp8ZOuP2X5k7qXffuGtY6D7dKzkbIOfoNmCI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=H50tEFWA; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="H50tEFWA" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-c85a2ed88c8so1312360a12.3 for ; Sun, 31 May 2026 23:51:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780296700; x=1780901500; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=dEuvk7i7rqZfwCAbLKkptmIQlUbXcNoFD9xb5HxF2jE=; b=H50tEFWA33pctHyuQVj9SMjh6JyyFxqHYMOxjEWbUvlPRkXzKS12aDApJFHSjv+XT7 1OjHXSVjbXefW9Joh31OeqcVDz5uANqnItU6GGRfkrghbT86tqBBIkLsbeqGiMF4Gnpv TyE9eKSfDZ5lnLhVmvw/qGYBVkIVVVA9ueOACUl6t89VfB4KF5m7XIi1ObcZkSJcq7iy CNEoQwLlECfvu5jYjKGyvJc5KqEjTAbmqA4/DGXm3WBFa2CRzkD8bvrRNNvLmXYVgQlZ i02X44R1IVK94KLXwuRAejRhsFQv9R01xbNUzQsIYEoEvJqjA8UUYgOeQ6zLuVU58XU1 obFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780296700; x=1780901500; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=dEuvk7i7rqZfwCAbLKkptmIQlUbXcNoFD9xb5HxF2jE=; b=EjasP3yYz0IAlhLMTwPJYwqd5TqvKuFz0rA2npTnOuTKdRH6ROFyRaCxRm0SxtLRPf ozFUxtjp4vV+tvgwVqaG1o1M3jr7YKF25Bf/FroeonlplqNWwNC8RcaDqfOY205x55FV wZl/SHLxU/a5i4QkK+92Bm/+7A5x67RA1d/9ScHqGhNuG1426/ImjUEQjq4Jy191Iz3J IYZ29pTwU7jeqBaqEDrfikdQQeGpblKr3KbQgacZGwUEMvcyV974ii1bPTMB8OpMYtC5 yPrYZ/kdsUT0xlhQRm6pIzJrTw8IvDilcbjsHfayHbEYx/Yno59WaVMcCuawyjdawUiV 7iDQ== X-Forwarded-Encrypted: i=1; AFNElJ+nba5dL7sbmpfnvUAHy90k6oaBzxPlfvr6OWE8RIJUA+AlD8uJ8rvYvmxD9mH3A7LWN2i33ALXU/DOXZE=@vger.kernel.org X-Gm-Message-State: AOJu0YzGNl0dyyJjh8yfgvOeWh9RXabaRQYSYwt34p7RLdOu1g4PCNpR c4urQVojX8SbhJmxAIaCwpZgQQQr4rDYqAeSTTGv+Qsn9vdPCTiCuD7oqV4Pses62wmgqcNCgUA EjQ== X-Received: from pgng19.prod.google.com ([2002:a63:3753:0:b0:c85:7a10:54e4]) (user=wakel job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:5482:b0:3b2:8675:4866 with SMTP id adf61e73a8af0-3b4280a5aa4mr8928004637.31.1780296699772; Sun, 31 May 2026 23:51:39 -0700 (PDT) Date: Mon, 1 Jun 2026 06:51:24 +0000 In-Reply-To: <20260601065126.3623867-1-wakel@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260601065126.3623867-1-wakel@google.com> X-Mailer: git-send-email 2.54.0.823.g6e5bcc1fc9-goog Message-ID: <20260601065126.3623867-6-wakel@google.com> Subject: [PATCH 5/7] selftests/futex: Migrate futex_numa_mpol to harness From: Wake Liu To: Thomas Gleixner , Ingo Molnar , Shuah Khan , linux-kselftest@vger.kernel.org Cc: Peter Zijlstra , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , Carlos Llamas , linux-kernel@vger.kernel.org, wakel@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Migrate futex_numa_mpol test to the kselftest harness framework, removing mixed legacy ksft_* API usages and passing test metadata to helper= functions. Signed-off-by: Wake Liu --- .../futex/functional/futex_numa_mpol.c | 109 ++++++++---------- 1 file changed, 51 insertions(+), 58 deletions(-) diff --git a/tools/testing/selftests/futex/functional/futex_numa_mpol.c b/t= ools/testing/selftests/futex/functional/futex_numa_mpol.c index 78c0f7a59e17..18dc8e54aa96 100644 --- a/tools/testing/selftests/futex/functional/futex_numa_mpol.c +++ b/tools/testing/selftests/futex/functional/futex_numa_mpol.c @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef LIBNUMA_VER_SUFFICIENT #include #include @@ -54,7 +55,7 @@ static void *thread_lock_fn(void *arg) return NULL; } =20 -static void create_max_threads(void *futex_ptr) +static void create_max_threads(struct __test_metadata *_metadata, void *fu= tex_ptr) { int i, ret; =20 @@ -63,28 +64,26 @@ static void create_max_threads(void *futex_ptr) thread_args[i].flags =3D FUTEX2_SIZE_U32 | FUTEX_PRIVATE_FLAG | FUTEX2_N= UMA; thread_args[i].result =3D 0; ret =3D pthread_create(&threads[i], NULL, thread_lock_fn, &thread_args[i= ]); - if (ret) - ksft_exit_fail_msg("pthread_create failed\n"); + ASSERT_EQ(ret, 0) TH_LOG("pthread_create failed"); } } =20 -static void join_max_threads(void) +static void join_max_threads(struct __test_metadata *_metadata) { int i, ret; =20 for (i =3D 0; i < MAX_THREADS; i++) { ret =3D 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", i); } } =20 -static void __test_futex(void *futex_ptr, int err_value, unsigned int fute= x_flags) +static void __test_futex(struct __test_metadata *_metadata, void *futex_pt= r, int err_value, unsigned int futex_flags) { - int to_wake, ret, i, need_exit =3D 0; + int to_wake, ret, i; =20 pthread_barrier_init(&barrier_main, NULL, MAX_THREADS + 1); - create_max_threads(futex_ptr); + create_max_threads(_metadata, futex_ptr); pthread_barrier_wait(&barrier_main); to_wake =3D MAX_THREADS; =20 @@ -92,45 +91,43 @@ static void __test_futex(void *futex_ptr, int err_value= , unsigned int futex_flag ret =3D futex2_wake(futex_ptr, to_wake, futex_flags); =20 if (err_value) { - if (ret >=3D 0) - ksft_exit_fail_msg("futex2_wake(%d, 0x%x) should fail, but didn't\n", - to_wake, futex_flags); + EXPECT_LT(ret, 0) + TH_LOG("futex2_wake(%d, 0x%x) should fail, but didn't", + to_wake, futex_flags); =20 - if (errno !=3D err_value) - ksft_exit_fail_msg("futex2_wake(%d, 0x%x) expected error was %d, but r= eturned %d (%s)\n", - to_wake, futex_flags, err_value, errno, strerror(errno)); + EXPECT_EQ(errno, err_value) + TH_LOG("futex2_wake(%d, 0x%x) expected error was %d, but returned %d (= %s)", + to_wake, futex_flags, err_value, errno, strerror(errno)); =20 break; } if (ret < 0) { - ksft_exit_fail_msg("Failed futex2_wake(%d, 0x%x): %m\n", - to_wake, futex_flags); + ASSERT_GE(ret, 0) + TH_LOG("Failed futex2_wake(%d, 0x%x): %s", + to_wake, futex_flags, strerror(errno)); } if (!ret) usleep(50); to_wake -=3D ret; =20 } while (to_wake); - join_max_threads(); + join_max_threads(_metadata); =20 for (i =3D 0; i < MAX_THREADS; i++) { - if (err_value && thread_args[i].result !=3D -1) { - ksft_print_msg("Thread %d should fail but succeeded (%d)\n", + if (err_value) { + EXPECT_EQ(thread_args[i].result, -1) + TH_LOG("Thread %d should fail but succeeded (%d)", i, thread_args[i].result); - need_exit =3D 1; - } - if (!err_value && thread_args[i].result !=3D 0) { - ksft_print_msg("Thread %d failed (%d)\n", i, thread_args[i].result); - need_exit =3D 1; + } else { + EXPECT_EQ(thread_args[i].result, 0) + TH_LOG("Thread %d failed (%d)", i, thread_args[i].result); } } - if (need_exit) - ksft_exit_fail_msg("Aborting due to earlier errors.\n"); } =20 -static void test_futex(void *futex_ptr, int err_value) +static void test_futex(struct __test_metadata *_metadata, void *futex_ptr,= int err_value) { - __test_futex(futex_ptr, err_value, FUTEX2_SIZE_U32 | FUTEX_PRIVATE_FLAG |= FUTEX2_NUMA); + __test_futex(_metadata, futex_ptr, err_value, FUTEX2_SIZE_U32 | FUTEX_PRI= VATE_FLAG | FUTEX2_NUMA); } =20 TEST(futex_numa_mpol) @@ -141,43 +138,41 @@ TEST(futex_numa_mpol) =20 mem_size =3D sysconf(_SC_PAGE_SIZE); futex_ptr =3D mmap(NULL, mem_size * 2, PROT_READ | PROT_WRITE, MAP_PRIVAT= E | MAP_ANONYMOUS, 0, 0); - if (futex_ptr =3D=3D MAP_FAILED) - ksft_exit_fail_msg("mmap() for %d bytes failed\n", mem_size); + ASSERT_NE(futex_ptr, MAP_FAILED) + TH_LOG("mmap() for %d bytes failed: %s", mem_size, strerror(errno)); =20 /* Create an invalid memory region for the "Memory out of range" test */ mprotect(futex_ptr + mem_size, mem_size, PROT_NONE); =20 futex_numa =3D futex_ptr; =20 - ksft_print_msg("Regular test\n"); + TH_LOG("Regular test"); futex_numa->futex =3D 0; futex_numa->numa =3D FUTEX_NO_NODE; - test_futex(futex_ptr, 0); + test_futex(_metadata, futex_ptr, 0); =20 - if (futex_numa->numa =3D=3D FUTEX_NO_NODE) - ksft_exit_fail_msg("NUMA node is left uninitialized\n"); + EXPECT_NE(futex_numa->numa, FUTEX_NO_NODE) + TH_LOG("NUMA node is left uninitialized"); =20 /* FUTEX2_NUMA futex must be 8-byte aligned */ - ksft_print_msg("Mis-aligned futex\n"); - test_futex(futex_ptr + mem_size - 4, EINVAL); + TH_LOG("Mis-aligned futex"); + test_futex(_metadata, futex_ptr + mem_size - 4, EINVAL); =20 - ksft_print_msg("Memory out of range\n"); - test_futex(futex_ptr + mem_size, EFAULT); + TH_LOG("Memory out of range"); + test_futex(_metadata, futex_ptr + mem_size, EFAULT); =20 futex_numa->numa =3D FUTEX_NO_NODE; mprotect(futex_ptr, mem_size, PROT_READ); - ksft_print_msg("Memory, RO\n"); - test_futex(futex_ptr, EFAULT); + TH_LOG("Memory, RO"); + test_futex(_metadata, futex_ptr, EFAULT); =20 mprotect(futex_ptr, mem_size, PROT_NONE); - ksft_print_msg("Memory, no access\n"); - test_futex(futex_ptr, EFAULT); + TH_LOG("Memory, no access"); + test_futex(_metadata, futex_ptr, EFAULT); =20 mprotect(futex_ptr, mem_size, PROT_READ | PROT_WRITE); - ksft_print_msg("Memory back to RW\n"); - test_futex(futex_ptr, 0); - - ksft_test_result_pass("futex2 memory boundary tests passed\n"); + TH_LOG("Memory back to RW"); + test_futex(_metadata, futex_ptr, 0); =20 /* MPOL test. Does not work as expected */ #ifdef LIBNUMA_VER_SUFFICIENT @@ -190,25 +185,23 @@ TEST(futex_numa_mpol) sizeof(nodemask) * 8, 0); if (ret =3D=3D 0) { ret =3D numa_set_mempolicy_home_node(futex_ptr, mem_size, i, 0); - if (ret !=3D 0) - ksft_exit_fail_msg("Failed to set home node: %m, %d\n", errno); + ASSERT_EQ(ret, 0) + TH_LOG("Failed to set home node: %s, %d", strerror(errno), errno); =20 - ksft_print_msg("Node %d test\n", i); + TH_LOG("Node %d test", i); futex_numa->futex =3D 0; futex_numa->numa =3D FUTEX_NO_NODE; =20 ret =3D futex2_wake(futex_ptr, 0, FUTEX2_SIZE_U32 | FUTEX_PRIVATE_FLAG = | FUTEX2_NUMA | FUTEX2_MPOL); - if (ret < 0) - ksft_test_result_fail("Failed to wake 0 with MPOL: %m\n"); - if (futex_numa->numa !=3D i) { - ksft_exit_fail_msg("Returned NUMA node is %d expected %d\n", - futex_numa->numa, i); - } + EXPECT_GE(ret, 0) + TH_LOG("Failed to wake 0 with MPOL: %s", strerror(errno)); + EXPECT_EQ(futex_numa->numa, i) + TH_LOG("Returned NUMA node is %d expected %d", + futex_numa->numa, i); } } - ksft_test_result_pass("futex2 MPOL hints test passed\n"); #else - ksft_test_result_skip("futex2 MPOL hints test requires libnuma 2.0.18+\n"= ); + SKIP(return, "futex2 MPOL hints test requires libnuma 2.0.18+"); #endif munmap(futex_ptr, mem_size * 2); } --=20 2.54.0.823.g6e5bcc1fc9-goog From nobody Mon Jun 8 06:36:18 2026 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C3AA63822A5 for ; Mon, 1 Jun 2026 06:51:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296706; cv=none; b=QN4wWMps2Goy+t2F1uqN7wslxduiF6rg6Ttd0qNW79xvz3ygO/BnrbgJ6G3nRDXqP1LaALj116fBHqI9LM7mD/tuS8hV9YKE1xDI7h7GvS1AX4W+79B6DTSyhvroJmLPioOyqIy/rFXxJNR9j84mI4YLD7D2OOesD612DPjR2So= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296706; c=relaxed/simple; bh=pDvCT3nXHlU7+Qmyj6Da0J3AxTPetMwuXX+Hgvkvx00=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kG3IWqJE3QC0wefx8JpTbxSq1tBK1p3ZhYU5+XznvHS8/McQFt8Dp1e2zpkyxGpi+Nq2c/PJpI4O1ynsSYdiOhsi8PbQNLuuMBr2mqZrc9ZR9ba/GHfZkM6mImB1ffnGRJC6rttjY6PIojsVeLwZBjUnvU1X2S+Y/GkKrw5EDUE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=fQX0gAyh; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="fQX0gAyh" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-8423770d72dso1801896b3a.3 for ; Sun, 31 May 2026 23:51:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780296702; x=1780901502; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=LsfNw+BauM7fB3mJaL1tUgJDsLO/ObAtcy7sWXgWNLE=; b=fQX0gAyhwl3aqVks2IX+htjaUOWpxS/Hn/DTp0jLyh8ne+hLtvEfPwOZCwAgaBHwxX kZgjk7XEkoe8eV4/rqNfDjsXyHJ4qW9iDoXdRpPRd3E/bQV5L6KBCB4/nuh0EKjYznsG wP3k636Qxfrij4ErfUjCKcmgGRaJUwKU8462meKmiVDSTJ+rDZLZvJJIiNbdfUQgzpqk QUAGs7Wyl8RatZkyoc19OAC0+7/Xi4HX0jFeH6h+7XvibbgOjWufKra4C6LRI7E1AoGG KzMn5oF0uEzTlMXdTq44P0CGWXcfKrqKmui8kh7+UMOl3Czrl1OcwrH4cLolgD7h/RNR AVnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780296702; x=1780901502; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=LsfNw+BauM7fB3mJaL1tUgJDsLO/ObAtcy7sWXgWNLE=; b=hvwZZ2ltitfwPkepgYn6NstHKx//FfsM4dBGXdHk2cGgFq9iz8E7d19xe4a8MI8u6E BEczAEG5wc13EGCAsjQoVzztHsDchuHgmS4gpBJPGDJViZka08Q7aRhplLSTO0CSUCBk LEsIcjBP3qNP1V+RfUD6DrcFsY535Ob24nIwdz0iBGnSeITS631/Pgf6tTAfHt628EcH 62gZbRh/F83jaCtp5li/CFj8OeKUvDDEkuGg2S7roMFW9yU9wFkis3SAxqbo9fwMZfH2 I+GxtgDgkDq9P+6+31cvTB+BeoNwkNC0NEXPlW1T1WK/OUa6uUhhODeqTbTlZO1/SKtD SJGA== X-Forwarded-Encrypted: i=1; AFNElJ+JKLV2R8XuzZAZlL3yBtehjI0+/WDfIsOV2icd44QKc//2xAgSSUyEQFRSTCOaOTGCiTONCuc6sLaKCgo=@vger.kernel.org X-Gm-Message-State: AOJu0YypzfUVG88uOttRAkDWKm8qQI6TvFsSsqK2ND8++cJd6x30V3vU 2tWpwpBvjMlmvFJqRCIL3+LRWCCDYltRTPe9dDqtyw2zhdJNEUNnxF79lexoXlCc6YJpZaka8R0 iNQ== X-Received: from pfsy9.prod.google.com ([2002:a05:6a00:389:b0:842:1c68:3772]) (user=wakel job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:3a17:b0:82f:355a:857e with SMTP id d2e1a72fcca58-842257098f3mr9099839b3a.47.1780296701652; Sun, 31 May 2026 23:51:41 -0700 (PDT) Date: Mon, 1 Jun 2026 06:51:25 +0000 In-Reply-To: <20260601065126.3623867-1-wakel@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260601065126.3623867-1-wakel@google.com> X-Mailer: git-send-email 2.54.0.823.g6e5bcc1fc9-goog Message-ID: <20260601065126.3623867-7-wakel@google.com> Subject: [PATCH 6/7] selftests/futex: Migrate futex_priv_hash to harness From: Wake Liu To: Thomas Gleixner , Ingo Molnar , Shuah Khan , linux-kselftest@vger.kernel.org Cc: Peter Zijlstra , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , Carlos Llamas , linux-kernel@vger.kernel.org, wakel@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- .../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/t= ools/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 #include #include +#include =20 #include #include @@ -39,31 +40,27 @@ static int futex_hash_slots_get(void) return prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_GET_SLOTS); } =20 -static void futex_hash_slots_set_verify(int slots) +static void futex_hash_slots_set_verify(struct __test_metadata *_metadata,= int slots) { int ret; =20 ret =3D futex_hash_slots_set(slots); - if (ret !=3D 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 =3D futex_hash_slots_get(); - if (ret !=3D 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)); } =20 -static void futex_hash_slots_set_must_fail(int slots) +static void futex_hash_slots_set_must_fail(struct __test_metadata *_metada= ta, int slots) { int ret; =20 ret =3D 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); } =20 static void *thread_return_fn(void *arg) @@ -82,32 +79,32 @@ static void *thread_lock_fn(void *arg) return NULL; } =20 -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; =20 for (i =3D 0; i < MAX_THREADS; i++) { ret =3D 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)); } } =20 -static void join_max_threads(void) +static void join_max_threads(struct __test_metadata *_metadata) { int i, ret; =20 for (i =3D 0; i < MAX_THREADS; i++) { ret =3D 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)); } } =20 #define SEC_IN_NSEC 1000000000 #define MSEC_IN_NSEC 1000000 =20 -static void futex_dummy_op(void) +static void futex_dummy_op(struct __test_metadata *_metadata) { pthread_mutex_t lock =3D PTHREAD_MUTEX_INITIALIZER; struct timespec timeout; @@ -121,11 +118,11 @@ static void futex_dummy_op(void) timeout.tv_sec++; } ret =3D pthread_mutex_timedlock(&lock, &timeout); - if (ret =3D=3D 0) - ksft_exit_fail_msg("Successfully locked an already locked mutex.\n"); + ASSERT_NE(ret, 0) + TH_LOG("Successfully locked an already locked mutex"); =20 - if (ret !=3D ETIMEDOUT) - ksft_exit_fail_msg("pthread_mutex_timedlock() did not timeout: %d.\n", r= et); + ASSERT_EQ(ret, ETIMEDOUT) + TH_LOG("pthread_mutex_timedlock() did not timeout: %d", ret); } =20 static const char *test_msg_auto_create =3D "Automatic hash bucket init on= thread creation.\n"; @@ -140,50 +137,45 @@ TEST(priv_hash) ret =3D pthread_mutexattr_init(&mutex_attr_pi); ret |=3D pthread_mutexattr_setprotocol(&mutex_attr_pi, PTHREAD_PRIO_INHER= IT); ret |=3D pthread_mutex_init(&global_lock, &mutex_attr_pi); - if (ret !=3D 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 =3D futex_hash_slots_get(); - if (ret !=3D 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)); =20 - ksft_test_result_pass("Basic get slots and immutable status.\n"); ret =3D pthread_create(&threads[0], NULL, thread_return_fn, NULL); - if (ret !=3D 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)); =20 ret =3D pthread_join(threads[0], NULL); - if (ret !=3D 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)); =20 /* First thread, has to initialize private hash */ futex_slots1 =3D futex_hash_slots_get(); - if (futex_slots1 <=3D 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_creat= e); =20 online_cpus =3D sysconf(_SC_NPROCESSORS_ONLN); ret =3D pthread_barrier_init(&barrier_main, NULL, MAX_THREADS + 1); - if (ret !=3D 0) - ksft_exit_fail_msg("pthread_barrier_init failed: %m.\n"); + ASSERT_EQ(ret, 0) + TH_LOG("pthread_barrier_init failed: %s", strerror(errno)); =20 ret =3D pthread_mutex_lock(&global_lock); - if (ret !=3D 0) - ksft_exit_fail_msg("pthread_mutex_lock failed: %m.\n"); + ASSERT_EQ(ret, 0) + TH_LOG("pthread_mutex_lock failed: %s", strerror(errno)); =20 counter =3D 0; - create_max_threads(thread_lock_fn); + create_max_threads(_metadata, thread_lock_fn); pthread_barrier_wait(&barrier_main); =20 /* * 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 =3D 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 =3D pthread_mutex_unlock(&global_lock); =20 /* 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); =20 ret =3D 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); =20 - futex_hash_slots_set_verify(2); - join_max_threads(); - ksft_test_result(counter =3D=3D MAX_THREADS, "Created and waited for %d o= f %d threads\n", - counter, MAX_THREADS); counter =3D 0; /* Once the user set something, auto resize must be disabled */ ret =3D pthread_barrier_init(&barrier_main, NULL, MAX_THREADS); + ASSERT_EQ(ret, 0) + TH_LOG("pthread_barrier_init failed: %s", strerror(errno)); =20 - create_max_threads(thread_lock_fn); - join_max_threads(); + create_max_threads(_metadata, thread_lock_fn); + join_max_threads(_metadata); =20 ret =3D futex_hash_slots_get(); - ksft_test_result(ret =3D=3D 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); =20 - 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); =20 /* * Once the global hash has been requested, then this requested can not * be undone. */ ret =3D futex_hash_slots_set(0); - ksft_test_result(ret =3D=3D 0, "Global hash request\n"); - if (ret !=3D 0) - return; + ASSERT_EQ(ret, 0) + TH_LOG("Global hash request failed: %s", strerror(errno)); =20 - 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); =20 ret =3D pthread_barrier_init(&barrier_main, NULL, MAX_THREADS); - if (ret !=3D 0) - ksft_exit_fail_msg("pthread_barrier_init failed: %m\n"); + ASSERT_EQ(ret, 0) + TH_LOG("pthread_barrier_init failed: %s", strerror(errno)); =20 - create_max_threads(thread_lock_fn); - join_max_threads(); + create_max_threads(_metadata, thread_lock_fn); + join_max_threads(_metadata); =20 ret =3D futex_hash_slots_get(); - ksft_test_result(ret =3D=3D 0, "Continue to use global hash\n"); + EXPECT_EQ(ret, 0) + TH_LOG("Continue to use global hash failed"); } =20 TEST_HARNESS_MAIN --=20 2.54.0.823.g6e5bcc1fc9-goog From nobody Mon Jun 8 06:36:18 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B65363806CE for ; Mon, 1 Jun 2026 06:51:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296710; cv=none; b=rig71RmZUo1u3McREanepytLu2I2+2JDiqY1HyLlkPBg8XKeos7FXT4CYZF6DXd7kQ9OHiluDf6KYPOyL/34bH5CWBnS7w/JLhU/IBjkYUeOByb2L69fbDWtJZtgC6BU5zlUltYpNh3ckBu5Um6ZkbBP+x4LlTzXMwI1FJjO38w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780296710; c=relaxed/simple; bh=gwxob2EZvulYK9ds/Mqv1DMR+vDx8ag+CcujK4k5Wow=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Pkv5oe6wwEqnD8lk69YVY2UMilX4zt5DYjsJEZTCNQ72Ljpv7s4C9ub3MM6OrfeSD9JC870Qj2z6WZb7+S3gMvzHoHAHuuXgaKVBs0ztwC1vvoNViBz5KsdTblJbK53kg3/OMNXYHJZHxTv/ww+0RuqZ7zQ6v0feZoGJEaZsKzs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=p6LXqWc9; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--wakel.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="p6LXqWc9" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-c85a2cde332so525166a12.3 for ; Sun, 31 May 2026 23:51:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780296704; x=1780901504; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=gj/zqebitZEjvXoiM48+KkCnu32ZUykHthRZNwA4NOU=; b=p6LXqWc9lIAN+CrneIYmW/Ngqx9E/VqUWU2wSbX6s/z1FUSCQZzuozgWBKWdZqq2Jh BUG8VLJ2wWIItgTWlx/5/Hzms4iHaxuUPOU8UV8wm5gmletfloM3URKg6qtouyUmwRgh F2uoKCpJw/MNHRr/4SD450gkPhEQM7HpuQMHPYTB29M7J23AxuqUrssI8rLoeQUbHfYp vEK0BaYuMI1Bu9lHVGJCS7UHONrztqguX4zMIG4TNmmZj/0b7YrGqFRFxUtZGXvA083T 2/jUjboICqvOrxaO6CpmUnmnVsyo5WI5CrrPYdU04OHfqH2C9diTdI3twk/8EcRPH2z9 4Hzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780296704; x=1780901504; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gj/zqebitZEjvXoiM48+KkCnu32ZUykHthRZNwA4NOU=; b=X/Is5JxwisabT5K2sErFVRFuUk+UYT1YiOsA0LCwLY0KzJlCHjeHT9T7gAW8D9sOXx UlnLJOS6mezeTOafaMER1atlw2x4m/rsMWlFwXD3ZLTDjdeHxo8sk1lz7OiXK/lBDsiM OqUgs1qEv86olbt7eE5ABhqxBmy4cyugKmFxKamJB+8SivDILm2eiW+eVqLl2jH04wF2 FhyyDRSkDO5EVag8p/5bQOMOJzD61LBOcFV2svXvz1Bjdl9DCERRq+IgfbARKJBFpij+ 47ompYa2Behw7veuDITMxNmsIKsJWc/D0bvKlXlZiXRcwR3HOBhuq9bqFvXAfNknl5f2 8/tg== X-Forwarded-Encrypted: i=1; AFNElJ+x8ndL+MDGBt2BA61Q+D2QqS7zooQEHGfMkTpVV6r6jjF/5mam80l5jDPx4Lcpo17ahSdmf2FEgnXHOb0=@vger.kernel.org X-Gm-Message-State: AOJu0YwkapppAGm20zLQgKC8GzS1MRryy+jWkOq/MOoloJ8elXKoS5xP xYbGM209kH733UfGiexCrETd2cSdhTdUn8oBBpGazAJ5pZ/k9wGXvzYUfPGkIEg3ipEGuECuDCE uxw== X-Received: from pgc24.prod.google.com ([2002:a05:6a02:2f98:b0:c85:121a:8a22]) (user=wakel job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:b08d:b0:3b2:a86f:d38e with SMTP id adf61e73a8af0-3b427f5a847mr9719886637.36.1780296703565; Sun, 31 May 2026 23:51:43 -0700 (PDT) Date: Mon, 1 Jun 2026 06:51:26 +0000 In-Reply-To: <20260601065126.3623867-1-wakel@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260601065126.3623867-1-wakel@google.com> X-Mailer: git-send-email 2.54.0.823.g6e5bcc1fc9-goog Message-ID: <20260601065126.3623867-8-wakel@google.com> Subject: [PATCH 7/7] selftests/futex: Migrate robust_list to harness From: Wake Liu To: Thomas Gleixner , Ingo Molnar , Shuah Khan , linux-kselftest@vger.kernel.org Cc: Peter Zijlstra , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , Carlos Llamas , linux-kernel@vger.kernel.org, wakel@google.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Migrate robust_list test to the kselftest harness framework, removing mixed legacy ksft_* API usages and passing test metadata to cloned child functions via child_args struct. Also, fix an out-of-bounds waitpid bug during multithreaded tests. Signed-off-by: Wake Liu --- .../selftests/futex/functional/robust_list.c | 166 +++++++++--------- 1 file changed, 85 insertions(+), 81 deletions(-) diff --git a/tools/testing/selftests/futex/functional/robust_list.c b/tools= /testing/selftests/futex/functional/robust_list.c index e7d1254e18ca..d0b461962586 100644 --- a/tools/testing/selftests/futex/functional/robust_list.c +++ b/tools/testing/selftests/futex/functional/robust_list.c @@ -25,7 +25,7 @@ #define _GNU_SOURCE =20 #include "futextest.h" -#include "../../kselftest_harness.h" +#include "kselftest_harness.h" =20 #include #include @@ -35,11 +35,11 @@ #include #include #include +#include +#include =20 #define STACK_SIZE (1024 * 1024) - #define FUTEX_TIMEOUT 3 - #define SLEEP_US 100 =20 static pthread_barrier_t barrier, barrier2; @@ -58,30 +58,46 @@ static int get_robust_list(int pid, struct robust_list_= head **head, size_t *len_ * Basic lock struct, contains just the futex word and the robust list ele= ment * Real implementations have also a *prev to easily walk in the list */ +typedef _Atomic(unsigned int) atomic_futex_t; + struct lock_struct { - _Atomic(unsigned int) futex; + atomic_futex_t futex; struct robust_list list; }; =20 +struct child_args { + struct __test_metadata *_metadata; + void *arg; +}; + /* * Helper function to spawn a child thread. Returns -1 on error, pid on su= ccess */ -static int create_child(int (*fn)(void *arg), void *arg) +static int create_child(struct __test_metadata *_metadata, int (*fn)(void = *arg), void *arg) { char *stack; pid_t pid; + struct child_args *cargs =3D malloc(sizeof(*cargs)); + + if (!cargs) + return -1; + cargs->_metadata =3D _metadata; + cargs->arg =3D arg; =20 stack =3D mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); - if (stack =3D=3D MAP_FAILED) + if (stack =3D=3D MAP_FAILED) { + free(cargs); return -1; + } =20 stack +=3D STACK_SIZE; =20 - pid =3D clone(fn, stack, CLONE_VM | SIGCHLD, arg); - - if (pid =3D=3D -1) + pid =3D clone(fn, stack, CLONE_VM | SIGCHLD, cargs); + if (pid =3D=3D -1) { + free(cargs); return -1; + } =20 return pid; } @@ -110,7 +126,7 @@ static int set_list(struct robust_list_head *head) */ static int mutex_lock(struct lock_struct *lock, struct robust_list_head *h= ead, bool error_inject) { - _Atomic(unsigned int) *futex =3D &lock->futex; + atomic_futex_t *futex =3D &lock->futex; unsigned int zero =3D 0; pid_t tid =3D gettid(); int ret =3D -1; @@ -170,21 +186,19 @@ static int mutex_lock(struct lock_struct *lock, struc= t robust_list_head *head, b */ static int child_fn_lock(void *arg) { - struct lock_struct *lock =3D arg; + struct child_args *cargs =3D arg; + struct __test_metadata *_metadata =3D cargs->_metadata; + struct lock_struct *lock =3D cargs->arg; struct robust_list_head head; int ret; =20 + free(cargs); + ret =3D set_list(&head); - if (ret) { - ksft_test_result_fail("set_robust_list error\n"); - return ret; - } + ASSERT_EQ(ret, 0) TH_LOG("set_robust_list error"); =20 ret =3D mutex_lock(lock, &head, false); - if (ret) { - ksft_test_result_fail("mutex_lock error\n"); - return ret; - } + ASSERT_EQ(ret, 0) TH_LOG("mutex_lock error"); =20 pthread_barrier_wait(&barrier); =20 @@ -207,7 +221,7 @@ static int child_fn_lock(void *arg) TEST(test_robustness) { struct lock_struct lock =3D { .futex =3D 0 }; - _Atomic(unsigned int) *futex =3D &lock.futex; + atomic_futex_t *futex =3D &lock.futex; struct robust_list_head head; int ret, pid, wstatus; =20 @@ -221,7 +235,7 @@ TEST(test_robustness) ret =3D pthread_barrier_init(&barrier, NULL, 2); ASSERT_EQ(ret, 0); =20 - pid =3D create_child(&child_fn_lock, &lock); + pid =3D create_child(_metadata, &child_fn_lock, &lock); ASSERT_NE(pid, -1); =20 pthread_barrier_wait(&barrier); @@ -238,9 +252,7 @@ TEST(test_robustness) wait(&wstatus); pthread_barrier_destroy(&barrier); =20 - /* Pass only if the child hasn't return error */ - if (!WEXITSTATUS(wstatus)) - ksft_test_result_pass("%s\n", __func__); + EXPECT_EQ(WEXITSTATUS(wstatus), 0) TH_LOG("child failed"); } =20 /* @@ -266,8 +278,6 @@ TEST(test_set_robust_list_invalid_size) ret =3D set_robust_list(&head, 0); ASSERT_EQ(ret, -1); ASSERT_EQ(errno, EINVAL); - - ksft_test_result_pass("%s\n", __func__); } =20 /* @@ -294,20 +304,19 @@ TEST(test_get_robust_list_self) ASSERT_EQ(ret, 0); ASSERT_EQ(get_head, &head2); ASSERT_EQ(head_size, len_ptr); - - ksft_test_result_pass("%s\n", __func__); } =20 static int child_list(void *arg) { - struct robust_list_head *head =3D arg; + struct child_args *cargs =3D arg; + struct __test_metadata *_metadata =3D cargs->_metadata; + struct robust_list_head *head =3D cargs->arg; int ret; =20 + free(cargs); + ret =3D set_robust_list(head, sizeof(*head)); - if (ret) { - ksft_test_result_fail("set_robust_list error\n"); - return -1; - } + ASSERT_EQ(ret, 0) TH_LOG("set_robust_list error"); =20 /* * After setting the list head, wait until the main thread can call @@ -337,7 +346,7 @@ TEST(test_get_robust_list_child) ret =3D pthread_barrier_init(&barrier2, NULL, 2); ASSERT_EQ(ret, 0); =20 - tid =3D create_child(&child_list, &head); + tid =3D create_child(_metadata, &child_list, &head); ASSERT_NE(tid, -1); =20 pthread_barrier_wait(&barrier); @@ -352,28 +361,24 @@ TEST(test_get_robust_list_child) pthread_barrier_destroy(&barrier); pthread_barrier_destroy(&barrier2); =20 - /* Pass only if the child hasn't return error */ - if (!WEXITSTATUS(wstatus)) - ksft_test_result_pass("%s\n", __func__); + EXPECT_EQ(WEXITSTATUS(wstatus), 0) TH_LOG("child failed"); } =20 static int child_fn_lock_with_error(void *arg) { - struct lock_struct *lock =3D arg; + struct child_args *cargs =3D arg; + struct __test_metadata *_metadata =3D cargs->_metadata; + struct lock_struct *lock =3D cargs->arg; struct robust_list_head head; int ret; =20 + free(cargs); + ret =3D set_list(&head); - if (ret) { - ksft_test_result_fail("set_robust_list error\n"); - return -1; - } + ASSERT_EQ(ret, 0) TH_LOG("set_robust_list error"); =20 ret =3D mutex_lock(lock, &head, true); - if (ret) { - ksft_test_result_fail("mutex_lock error\n"); - return -1; - } + ASSERT_EQ(ret, 0) TH_LOG("mutex_lock error"); =20 pthread_barrier_wait(&barrier); =20 @@ -391,7 +396,7 @@ static int child_fn_lock_with_error(void *arg) TEST(test_set_list_op_pending) { struct lock_struct lock =3D { .futex =3D 0 }; - _Atomic(unsigned int) *futex =3D &lock.futex; + atomic_futex_t *futex =3D &lock.futex; struct robust_list_head head; int ret, wstatus; =20 @@ -401,7 +406,7 @@ TEST(test_set_list_op_pending) ret =3D pthread_barrier_init(&barrier, NULL, 2); ASSERT_EQ(ret, 0); =20 - ret =3D create_child(&child_fn_lock_with_error, &lock); + ret =3D create_child(_metadata, &child_fn_lock_with_error, &lock); ASSERT_NE(ret, -1); =20 pthread_barrier_wait(&barrier); @@ -414,21 +419,21 @@ TEST(test_set_list_op_pending) wait(&wstatus); pthread_barrier_destroy(&barrier); =20 - /* Pass only if the child hasn't return error */ - if (!WEXITSTATUS(wstatus)) - ksft_test_result_pass("%s\n", __func__); - else - ksft_test_result_fail("%s\n", __func__); + EXPECT_EQ(WEXITSTATUS(wstatus), 0) TH_LOG("child failed"); } =20 #define CHILD_NR 10 =20 static int child_lock_holder(void *arg) { - struct lock_struct *locks =3D arg; + struct child_args *cargs =3D arg; + struct __test_metadata *_metadata =3D cargs->_metadata; + struct lock_struct *locks =3D cargs->arg; struct robust_list_head head; int i; =20 + free(cargs); + set_list(&head); =20 for (i =3D 0; i < CHILD_NR; i++) { @@ -447,22 +452,20 @@ static int child_lock_holder(void *arg) =20 static int child_wait_lock(void *arg) { - struct lock_struct *lock =3D arg; + struct child_args *cargs =3D arg; + struct __test_metadata *_metadata =3D cargs->_metadata; + struct lock_struct *lock =3D cargs->arg; struct robust_list_head head; int ret; =20 + free(cargs); + pthread_barrier_wait(&barrier2); ret =3D mutex_lock(lock, &head, false); + ASSERT_EQ(ret, 0) TH_LOG("mutex_lock error"); =20 - if (ret) { - ksft_test_result_fail("mutex_lock error\n"); - return -1; - } - - if (!(lock->futex & FUTEX_OWNER_DIED)) { - ksft_test_result_fail("futex not marked with FUTEX_OWNER_DIED\n"); - return -1; - } + ASSERT_TRUE(lock->futex & FUTEX_OWNER_DIED) + TH_LOG("futex not marked with FUTEX_OWNER_DIED"); =20 return 0; } @@ -482,18 +485,20 @@ TEST(test_robust_list_multiple_elements) ret =3D pthread_barrier_init(&barrier2, NULL, CHILD_NR + 1); ASSERT_EQ(ret, 0); =20 - pids[0] =3D create_child(&child_lock_holder, &locks); + pids[0] =3D create_child(_metadata, &child_lock_holder, &locks); + ASSERT_NE(pids[0], -1); =20 /* Wait until the locker thread takes the look */ pthread_barrier_wait(&barrier); =20 - for (i =3D 0; i < CHILD_NR; i++) - pids[i+1] =3D create_child(&child_wait_lock, &locks[i]); + for (i =3D 0; i < CHILD_NR; i++) { + pids[i+1] =3D create_child(_metadata, &child_wait_lock, &locks[i]); + ASSERT_NE(pids[i+1], -1); + } =20 - /* Wait for all children to return */ + /* Wait for all children to return (holder + all waiters) */ ret =3D 0; - - for (i =3D 0; i < CHILD_NR; i++) { + for (i =3D 0; i < CHILD_NR + 1; i++) { waitpid(pids[i], &wstatus, 0); if (WEXITSTATUS(wstatus)) ret =3D -1; @@ -502,22 +507,21 @@ TEST(test_robust_list_multiple_elements) pthread_barrier_destroy(&barrier); pthread_barrier_destroy(&barrier2); =20 - /* Pass only if the child hasn't return error */ - if (!ret) - ksft_test_result_pass("%s\n", __func__); + EXPECT_EQ(ret, 0) TH_LOG("One or more children failed"); } =20 static int child_circular_list(void *arg) { + struct child_args *cargs =3D arg; + struct __test_metadata *_metadata =3D cargs->_metadata; static struct robust_list_head head; struct lock_struct a, b, c; int ret; =20 + free(cargs); + ret =3D set_list(&head); - if (ret) { - ksft_test_result_fail("set_list error\n"); - return -1; - } + ASSERT_EQ(ret, 0) TH_LOG("set_list error"); =20 head.list.next =3D &a.list; =20 @@ -539,14 +543,14 @@ static int child_circular_list(void *arg) TEST(test_circular_list) { int wstatus; + pid_t pid; =20 - create_child(child_circular_list, NULL); + pid =3D create_child(_metadata, child_circular_list, NULL); + ASSERT_NE(pid, -1); =20 wait(&wstatus); =20 - /* Pass only if the child hasn't return error */ - if (!WEXITSTATUS(wstatus)) - ksft_test_result_pass("%s\n", __func__); + EXPECT_EQ(WEXITSTATUS(wstatus), 0) TH_LOG("child failed"); } =20 TEST_HARNESS_MAIN --=20 2.54.0.823.g6e5bcc1fc9-goog