From nobody Sat Jul 25 02:13:00 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA1CA3839BE; Mon, 20 Jul 2026 19:00:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784574012; cv=none; b=LcoQh8ClNsK0mJP8E9krdzbbehTNuoIXSTNqaWEN3EWZ0zGwg5ejK4WoS5fWc1a+NJE4g4z2umq2T5oMQIJbGroJlOMRPq0z5vMYUF1ZS3XgwWxU7r0+4X8dn18kazwPqjKGQr+Ub9lhr3O3dNRNhuUNw+QukW/T+9io/x7Pp+Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784574012; c=relaxed/simple; bh=LkT++VVKiw1S3JHJlqqbjGFwT0pR5FXHLFu8zBEZVxM=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=CYH1kUtx0xrFV6YCYU6PQappIl/1eHpNJqaMrbtvcKEWYWbwkQJX5RVlFcL9yRVJdYoDxwDXenPpe8H5diW8KpS5jzVQY2QkPKrrplxsHK6lO1+B1dSoaHFfvXrAjUDm9LlPBViTaD+m28n4tXv4VS/koL3MnaD3kw/jcPOjsBY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=vAF8NgT6; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=2k+LZBw7; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="vAF8NgT6"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="2k+LZBw7" Date: Mon, 20 Jul 2026 19:00:07 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1784574009; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oFnwMZjjTu5KskqEHlKEu9oO0scxr7ZGNRx/FbpVv28=; b=vAF8NgT6aBp2Z+CESi2KAGSecDI8aOR1eW4Dg4dl04OEL4PRxp8t5I/anK9MA8UNZdyk8g y1JCOpuFHjva0Hvsckzz765pZKuZOjhi4AuCuPSEw4WYHzracNhd4HEYqGsNdu3s6frD0M CuuFInif6zZGJt73Dr/Ta9NJTKo+UGKl7Tc4larU9vpKSb131yalv7aux6QEcNFaamLZtQ Uu10nH/+54nIsWcQXI+ymzHeCjM6WwHQCI9sT7hbo4UzuJAD0l7N7z63PUbXmKVwa2po8g gSCV2Axymw9b5vrxgULP+kKxLse5bhxly+UgaCHkUQ77wARfUIx+5QBIEDjXJg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1784574009; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oFnwMZjjTu5KskqEHlKEu9oO0scxr7ZGNRx/FbpVv28=; b=2k+LZBw7FY8rxkxO9JbijQkAZ1Iz8FdjzQvgYEPGD5i+/2KJOXWBLeVy1R5E2NoK0bpKJ6 4R/jz/YAzeO6vVDQ== From: "tip-bot2 for Yuwen Chen" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: locking/futex] selftests/futex: Provide thread creation and synchronization helpers Cc: Yuwen Chen , Thomas Gleixner , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <178457400711.2943223.18207382644253840889.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the locking/futex branch of tip: Commit-ID: 6c4a1b972643d72bd26f674677df8b5a6a3fe94f Gitweb: https://git.kernel.org/tip/6c4a1b972643d72bd26f674677df8b5a6= a3fe94f Author: Yuwen Chen AuthorDate: Mon, 18 May 2026 10:16:40 +08:00 Committer: Thomas Gleixner CommitterDate: Mon, 20 Jul 2026 20:58:51 +02:00 selftests/futex: Provide thread creation and synchronization helpers There are timing issues in the use of threads in some selftests for futexes as the tests rely on timed waits to ensure that the other test thread[s] reached the lock wait function in the kernel. That "works" on halfways idle systems, but fails under load which results in tests failing. Provide a set of helper functions to create test threads and to wait for them to reach the lock wait by monitoring /proc/$PID/wchan. [ tglx: Fixup coding style, move the timeout into the helper, adapt to test harness changes and massage change log ] Signed-off-by: Yuwen Chen Signed-off-by: Thomas Gleixner Link: https://patch.msgid.link/tencent_4C90BE98BBC48B38B9FBC6A95C45CF49F309= @qq.com --- tools/testing/selftests/futex/functional/Makefile | 3 +- tools/testing/selftests/futex/include/futex_thread.h | 117 ++++++++++- 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/futex/include/futex_thread.h diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/test= ing/selftests/futex/functional/Makefile index d59faf7..a03bd5a 100644 --- a/tools/testing/selftests/futex/functional/Makefile +++ b/tools/testing/selftests/futex/functional/Makefile @@ -11,7 +11,8 @@ endif =20 LOCAL_HDRS :=3D \ ../include/futextest.h \ - ../include/atomic.h + ../include/atomic.h \ + ../include/futex_thread.h TEST_GEN_PROGS :=3D \ futex_wait_timeout \ futex_wait_wouldblock \ diff --git a/tools/testing/selftests/futex/include/futex_thread.h b/tools/t= esting/selftests/futex/include/futex_thread.h new file mode 100644 index 0000000..a908829 --- /dev/null +++ b/tools/testing/selftests/futex/include/futex_thread.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _FUTEX_THREAD_H +#define _FUTEX_THREAD_H +#include +#include +#include +#include +#include + +#include "kselftest_harness.h" + +#define USEC_PER_SEC 1000000L +#define WAIT_FOR_THREAD_SECS 1 +#define WAIT_FOR_THREAD_USECS (WAIT_FOR_THREAD_SECS * USEC_PER_SEC) +#define WAIT_THREAD_RETRIES 100 + +struct futex_thread { + pthread_t thread; + pthread_barrier_t barrier; + pid_t tid; + int (*threadfn)(void *arg); + void *arg; + int retval; +}; + +static inline int __wait_for_thread(FILE *fp, struct __test_metadata *_met= adata) +{ + unsigned int sleep_time_us =3D WAIT_FOR_THREAD_USECS / WAIT_THREAD_RETRIE= S; + char buf[80] =3D ""; + + for (int i =3D 0; i < WAIT_THREAD_RETRIES; i++) { + if (!fgets(buf, sizeof(buf), fp)) + return EIO; + if (!strncmp(buf, "futex", 5)) + return 0; + usleep(sleep_time_us); + rewind(fp); + } + + TH_LOG("/proc/$PID/wchan contains \"%s\". Trying to continue.", buf); + return 0; +} + +static void *__futex_thread_fn(void *arg) +{ + struct futex_thread *t =3D arg; + + t->tid =3D gettid(); + pthread_barrier_wait(&t->barrier); + t->retval =3D t->threadfn(t->arg); + return NULL; +} + +/** + * futex_wait_for_thread - Wait for the child thread to sleep in the futex= context + * @t: Thread handle. + * @_metadata: Test metadata for TH_LOG() context + */ +static inline int futex_wait_for_thread(struct futex_thread *t, struct __t= est_metadata *_metadata) +{ + char fname[80]; + FILE *fp; + int res; + + snprintf(fname, sizeof(fname), "/proc/%d/wchan", t->tid); + fp =3D fopen(fname, "r"); + if (!fp) { + /* If /proc/... is not available, sleep */ + if (errno !=3D ENOENT) + return errno; + TH_LOG("/proc/$PID/wchan not accessible, continue with sleep()"); + sleep(WAIT_FOR_THREAD_SECS); + return 0; + } + + res =3D __wait_for_thread(fp, _metadata); + fclose(fp); + return res; +} + +/** + * futex_thread_create - Create a new thread for testing. + * @t: The handle of the newly created thread. + * @threadfn: The new thread starts execution by invoking threadfn + * @arg: The parameters passed to threadfn. + */ +static inline int futex_thread_create(struct futex_thread *t, int (*thread= fn)(void *), void *arg) +{ + pthread_barrier_init(&t->barrier, NULL, 2); + + t->tid =3D 0; + t->threadfn =3D threadfn; + t->arg =3D arg; + + if (pthread_create(&t->thread, NULL, __futex_thread_fn, t) < 0) { + int ret =3D errno; + pthread_barrier_destroy(&t->barrier); + return ret; + } + + pthread_barrier_wait(&t->barrier); + return 0; +} + +/** + * futex_thread_destroy - Wait for and reclaim the resources of the thread. + * @t: Thread handle. + */ +static inline int futex_thread_destroy(struct futex_thread *t) +{ + pthread_join(t->thread, NULL); + pthread_barrier_destroy(&t->barrier); + return t->retval; +} + +#endif