From nobody Tue Oct 7 10:32:56 2025 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 45FD92E091B for ; Thu, 10 Jul 2025 11:00:19 +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=1752145220; cv=none; b=pJZrtlfDAS2T9hLQzCZ8mNNaErlIu2cPysMPyxDTC+bAOdDh0NGnM5LHWAWBIJ1SFRhyEsO54shtczKWc4c2i0Pus6khsnu8QpNjNY6N5AiOem42DJxJJtbpwwk/v9sjzHzrvbJJtLZUBM+zBYDPDkEpEbm3N+864XoiaFSsnn0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752145220; c=relaxed/simple; bh=+ThNQJN0DbohqGKY+flN4X+Txz1uC7m/vPbBH2exJmI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sgZ4Bo90oX2DvSgVtKsT1oCfFLlKbQe3feU1Zc6KTLvTGFoPsRqXSP6hPkhknF95u/KtCSxKyPNUcH15qE33Th3S5F1zZ9fF53mXabbn4GN3C6GGC97pfgwmpgz2NCBJt1GyEv5Pfo2JEDvv21nSUGmiuXDgoN+5sNVYDEsoypc= 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=Bu6kFVZh; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=uRQdM4xD; 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="Bu6kFVZh"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="uRQdM4xD" From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752145217; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FZuOHQOhHu6YpFOEA+NkXfkqho+ptJIg0qyPO2GsLKM=; b=Bu6kFVZhWoTvm10K/ybg4YjV3BSk6UoPyz4paXiNtb+cQVpfc+vlFEeY8MpLpVDK9sESQq R1e2xT1E7uTdW07y8XKwWLZqCwr28nSg1RtuyEg+liCz1NO+vsWERJ0QaseIP1NLoe5H5F IXYrcQyhm+spq3/O7U0VJT3OB06K32RnN0r90611HXiARBpdQSzPlRJXkZEONtivFf67zf HbjfaxClLx+drsFTi+Y8xnq69bjKbYyo9tGLtpgT6C1dubw45Kf662+04XDlWEl3QRUiIm fAb76O6CXehz0e1Jkz9LxONn1FbxzkUyVxh5aOdAYmZ6bJO0mACjssg8Bkk1BA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752145217; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FZuOHQOhHu6YpFOEA+NkXfkqho+ptJIg0qyPO2GsLKM=; b=uRQdM4xDl1hi0bDqkoHE1YxjkTPs07617YeXmqFA/A8EbcIqtX0oFKYlJhwhrAt+QNuq+X BiI0xcXs+/IB3UBA== To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Andr=C3=A9=20Almeida?= , Darren Hart , Davidlohr Bueso , Ingo Molnar , Juri Lelli , Peter Zijlstra , Thomas Gleixner , Valentin Schneider , Waiman Long , Sebastian Andrzej Siewior Subject: [PATCH v2 1/6] selftests/futex: Adapt the private hash test to RCU related changes Date: Thu, 10 Jul 2025 13:00:06 +0200 Message-ID: <20250710110011.384614-2-bigeasy@linutronix.de> In-Reply-To: <20250710110011.384614-1-bigeasy@linutronix.de> References: <20250710110011.384614-1-bigeasy@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The auto scaling on create creation used to automatically assign the new hash because there was the private hash was unused and could be replaced right away. This is already racy because if the private hash is in use by a thread then the visibile resize will be delayed. With the upcoming change to wait for a RCU grace period before the hash can be assigned, the test will always fail. If the reported number of hash buckets is not updated after an auto scaling event, block on an acquired lock with a timeout. The timeout is the delay to wait towards a grace period and locking and a locked pthread_mutex_t ensure that glibc calls into kernel using futex operation which will assign new private hash if available. This will retry every 100ms up to 2 seconds in total. Signed-off-by: Sebastian Andrzej Siewior --- .../futex/functional/futex_priv_hash.c | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/futex/functional/futex_priv_hash.c b/t= ools/testing/selftests/futex/functional/futex_priv_hash.c index 24a92dc94eb86..625e3be4129c3 100644 --- a/tools/testing/selftests/futex/functional/futex_priv_hash.c +++ b/tools/testing/selftests/futex/functional/futex_priv_hash.c @@ -111,6 +111,30 @@ static void join_max_threads(void) } } =20 +#define SEC_IN_NSEC 1000000000 +#define MSEC_IN_NSEC 1000000 + +static void futex_dummy_op(void) +{ + pthread_mutex_t lock =3D PTHREAD_MUTEX_INITIALIZER; + struct timespec timeout; + int ret; + + pthread_mutex_lock(&lock); + clock_gettime(CLOCK_REALTIME, &timeout); + timeout.tv_nsec +=3D 100 * MSEC_IN_NSEC; + if (timeout.tv_nsec >=3D SEC_IN_NSEC) { + timeout.tv_nsec -=3D SEC_IN_NSEC; + timeout.tv_sec++; + } + ret =3D pthread_mutex_timedlock(&lock, &timeout); + if (ret =3D=3D 0) + ksft_exit_fail_msg("Succeffuly locked an already locked mutex.\n"); + + if (ret !=3D ETIMEDOUT) + ksft_exit_fail_msg("pthread_mutex_timedlock() did not timeout: %d.\n", r= et); +} + static void usage(char *prog) { printf("Usage: %s\n", prog); @@ -129,7 +153,7 @@ int main(int argc, char *argv[]) int futex_slots1, futex_slotsn, online_cpus; pthread_mutexattr_t mutex_attr_pi; int use_global_hash =3D 0; - int ret; + int ret, retry =3D 20; int c; =20 while ((c =3D getopt(argc, argv, "cghv:")) !=3D -1) { @@ -208,8 +232,24 @@ int main(int argc, char *argv[]) */ ksft_print_msg("Online CPUs: %d\n", online_cpus); if (online_cpus > 16) { +retry_getslots: futex_slotsn =3D futex_hash_slots_get(); if (futex_slotsn < 0 || futex_slots1 =3D=3D futex_slotsn) { + retry--; + /* + * Auto scaling on thread creation can be slightly delayed + * because it waits for a RCU grace period twice. The new + * private hash is assigned upon the first futex operation + * after grace period. + * To cover all this for testing purposes the function + * below will acquire a lock and acquire it again with a + * 100ms timeout which must timeout. This ensures we + * sleep for 100ms and issue a futex operation. + */ + if (retry > 0) { + futex_dummy_op(); + goto retry_getslots; + } ksft_print_msg("Expected increase of hash buckets but got: %d -> %d\n", futex_slots1, futex_slotsn); ksft_exit_fail_msg(test_msg_auto_inc); --=20 2.50.0 From nobody Tue Oct 7 10:32:56 2025 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 885442E54D9 for ; Thu, 10 Jul 2025 11:00:20 +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=1752145225; cv=none; b=W38fJw1JdyfgThLV2+jToKTSTK4pfO3Ty374W39KCzC/PQdDJw2cnmtejs9VMSiJCu1KlUqnDrV3ZTWchfPAFhHN3ZdoL+eWj9Uui2KPOCV/KUVyiOLJaJdin351z4uUXpHJv0pjDCxqNIUjbkXIcYhxYzXOLoAl/JZu3RseaRE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752145225; c=relaxed/simple; bh=S2fvBzXEckMv4p1um/LwQcwfL+o45XktE5tkQI0Cfog=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NtdARZ6ymsekSV4Ctpb7XW1Sxu70/haJUlu7WEZpSn9xOd4nDlPm3MtUh/416xK3FsrmPLe40DVdtqWyVNbobkNoSwM5Y2eoPvNKDJUiD+LTY59QWFFQT/A7kFkBsLlLGDHXGLzddTQZnFvu7UhExKC4AIe3DvMQkdNU2qifrew= 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=jIBN3tUF; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=XRUggE+q; 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="jIBN3tUF"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="XRUggE+q" From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752145217; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=73qagTk1kJMZ+DqvXnSmCpd8s99hTvT9ehk44SIIdec=; b=jIBN3tUFZ9k+AyuYOq7VOkmrTkGWoAUrYm4u5s6JHp9l0GDldP4r+8sungxgktr3Fk5UJD EXDboCP5ulbkij+8/Yv500mSUVR51U+VYnXazSvjrOP851prYW9s9wUZkfWaK4v0ILoTJR w00nkF9zP4mZrUKKNRi9vBkOi8qsDiN/LJSXz3evUdLthcMBhASEjEKnBtqTPoMB66RCEu 4KVmyu8wJoQEWGDqoRo+pTD3cAWRnkfKXLq5FzR+NkBVNhZ8XKRrin4L4kHZmPp+kg/3IG FeKfB8Qdtud4vpMrau/LVKz6O7MkKgSO+LacqjNbOmAz5hOMKkKIifOuAskFdg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752145217; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=73qagTk1kJMZ+DqvXnSmCpd8s99hTvT9ehk44SIIdec=; b=XRUggE+qWScL8dBM3ok7sAUUU57dzTthP39Xx3v9E1lRMKOuiEwApc2LO57W/fN8GNCtR+ Ib46bmEw8hLAjrBw== To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Andr=C3=A9=20Almeida?= , Darren Hart , Davidlohr Bueso , Ingo Molnar , Juri Lelli , Peter Zijlstra , Thomas Gleixner , Valentin Schneider , Waiman Long , Andrew Morton , David Hildenbrand , "Liam R. Howlett" , Lorenzo Stoakes , Michal Hocko , Mike Rapoport , Suren Baghdasaryan , Vlastimil Babka , linux-mm@kvack.org, Sebastian Andrzej Siewior Subject: [PATCH v2 2/6] futex: Use RCU-based per-CPU reference counting instead of rcuref_t Date: Thu, 10 Jul 2025 13:00:07 +0200 Message-ID: <20250710110011.384614-3-bigeasy@linutronix.de> In-Reply-To: <20250710110011.384614-1-bigeasy@linutronix.de> References: <20250710110011.384614-1-bigeasy@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Peter Zijlstra The use of rcuref_t for reference counting introduces a performance bottlen= eck when accessed concurrently by multiple threads during futex operations. Replace rcuref_t with special crafted per-CPU reference counters. The lifetime logic remains the same. The newly allocate private hash starts in FR_PERCPU state. In this state, e= ach futex operation that requires the private hash uses a per-CPU counter (an unsigned int) for incrementing or decrementing the reference count. When the private hash is about to be replaced, the per-CPU counters are migrated to a atomic_t counter mm_struct::futex_atomic. The migration process: - Waiting for one RCU grace period to ensure all users observe the current private hash. This can be skipped if a grace period elapsed since the private hash was assigned. - futex_private_hash::state is set to FR_ATOMIC, forcing all users to use mm_struct::futex_atomic for reference counting. - After a RCU grace period, all users are guaranteed to be using the atomic counter. The per-CPU counters can now be summed up and added to the atomic_t counter. If the resulting count is zero, the hash can be safely replaced. Otherwise, active users still hold a valid reference. - Once the atomic reference count drops to zero, the next futex operation will switch to the new private hash. call_rcu_hurry() is used to speed up transition which otherwise might be delay with RCU_LAZY. There is nothing wrong with using call_rcu(). The side effects would be that on auto scaling the new hash is used later and the SET_SLOTS prctl() will block longer. [bigeasy: commit description + mm get/ put_async] Cc: Andrew Morton Cc: David Hildenbrand Cc: Liam R. Howlett Cc: Lorenzo Stoakes Cc: Michal Hocko Cc: Mike Rapoport Cc: Suren Baghdasaryan Cc: Vlastimil Babka Cc: linux-mm@kvack.org Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Sebastian Andrzej Siewior --- include/linux/futex.h | 16 +-- include/linux/mm_types.h | 5 + include/linux/sched/mm.h | 2 +- init/Kconfig | 4 - kernel/fork.c | 8 +- kernel/futex/core.c | 243 ++++++++++++++++++++++++++++++++++++--- 6 files changed, 243 insertions(+), 35 deletions(-) diff --git a/include/linux/futex.h b/include/linux/futex.h index b37193653e6b5..9e9750f049805 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -85,18 +85,12 @@ int futex_hash_prctl(unsigned long arg2, unsigned long = arg3, unsigned long arg4) #ifdef CONFIG_FUTEX_PRIVATE_HASH int futex_hash_allocate_default(void); void futex_hash_free(struct mm_struct *mm); - -static inline void futex_mm_init(struct mm_struct *mm) -{ - RCU_INIT_POINTER(mm->futex_phash, NULL); - mm->futex_phash_new =3D NULL; - mutex_init(&mm->futex_hash_lock); -} +int futex_mm_init(struct mm_struct *mm); =20 #else /* !CONFIG_FUTEX_PRIVATE_HASH */ static inline int futex_hash_allocate_default(void) { return 0; } -static inline void futex_hash_free(struct mm_struct *mm) { } -static inline void futex_mm_init(struct mm_struct *mm) { } +static inline int futex_hash_free(struct mm_struct *mm) { return 0; } +static inline int futex_mm_init(struct mm_struct *mm) { return 0; } #endif /* CONFIG_FUTEX_PRIVATE_HASH */ =20 #else /* !CONFIG_FUTEX */ @@ -118,8 +112,8 @@ static inline int futex_hash_allocate_default(void) { return 0; } -static inline void futex_hash_free(struct mm_struct *mm) { } -static inline void futex_mm_init(struct mm_struct *mm) { } +static inline int futex_hash_free(struct mm_struct *mm) { return 0; } +static inline int futex_mm_init(struct mm_struct *mm) { return 0; } =20 #endif =20 diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index d6b91e8a66d6d..0f0662157066a 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -1070,6 +1070,11 @@ struct mm_struct { struct mutex futex_hash_lock; struct futex_private_hash __rcu *futex_phash; struct futex_private_hash *futex_phash_new; + /* futex-ref */ + unsigned long futex_batches; + struct rcu_head futex_rcu; + atomic_long_t futex_atomic; + unsigned int __percpu *futex_ref; #endif =20 unsigned long hiwater_rss; /* High-watermark of RSS usage */ diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index b13474825130f..2201da0afecc5 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -140,7 +140,7 @@ static inline bool mmget_not_zero(struct mm_struct *mm) =20 /* mmput gets rid of the mappings and all user-space */ extern void mmput(struct mm_struct *); -#ifdef CONFIG_MMU +#if defined(CONFIG_MMU) || defined(CONFIG_FUTEX_PRIVATE_HASH) /* same as above but performs the slow path from the async context. Can * be called from the atomic context as well */ diff --git a/init/Kconfig b/init/Kconfig index 666783eb50abd..af4c2f0854554 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1716,13 +1716,9 @@ config FUTEX_PI depends on FUTEX && RT_MUTEXES default y =20 -# -# marked broken for performance reasons; gives us one more cycle to sort t= hings out. -# config FUTEX_PRIVATE_HASH bool depends on FUTEX && !BASE_SMALL && MMU - depends on BROKEN default y =20 config FUTEX_MPOL diff --git a/kernel/fork.c b/kernel/fork.c index 1ee8eb11f38ba..0b885dcbde9af 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1046,7 +1046,6 @@ static struct mm_struct *mm_init(struct mm_struct *mm= , struct task_struct *p, RCU_INIT_POINTER(mm->exe_file, NULL); mmu_notifier_subscriptions_init(mm); init_tlb_flush_pending(mm); - futex_mm_init(mm); #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !defined(CONFIG_SPLIT_PMD_PTLO= CKS) mm->pmd_huge_pte =3D NULL; #endif @@ -1061,6 +1060,9 @@ static struct mm_struct *mm_init(struct mm_struct *mm= , struct task_struct *p, mm->def_flags =3D 0; } =20 + if (futex_mm_init(mm)) + goto fail_mm_init; + if (mm_alloc_pgd(mm)) goto fail_nopgd; =20 @@ -1090,6 +1092,8 @@ static struct mm_struct *mm_init(struct mm_struct *mm= , struct task_struct *p, fail_noid: mm_free_pgd(mm); fail_nopgd: + futex_hash_free(mm); +fail_mm_init: free_mm(mm); return NULL; } @@ -1145,7 +1149,7 @@ void mmput(struct mm_struct *mm) } EXPORT_SYMBOL_GPL(mmput); =20 -#ifdef CONFIG_MMU +#if defined(CONFIG_MMU) || defined(CONFIG_FUTEX_PRIVATE_HASH) static void mmput_async_fn(struct work_struct *work) { struct mm_struct *mm =3D container_of(work, struct mm_struct, diff --git a/kernel/futex/core.c b/kernel/futex/core.c index 90d53fb0ee9e1..1dcb4c8a2585d 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include =20 @@ -65,7 +64,7 @@ static struct { #define futex_queues (__futex_data.queues) =20 struct futex_private_hash { - rcuref_t users; + int state; unsigned int hash_mask; struct rcu_head rcu; void *mm; @@ -129,6 +128,12 @@ static struct futex_hash_bucket * __futex_hash(union futex_key *key, struct futex_private_hash *fph); =20 #ifdef CONFIG_FUTEX_PRIVATE_HASH +static bool futex_ref_get(struct futex_private_hash *fph); +static bool futex_ref_put(struct futex_private_hash *fph); +static bool futex_ref_is_dead(struct futex_private_hash *fph); + +enum { FR_PERCPU =3D 0, FR_ATOMIC }; + static inline bool futex_key_is_private(union futex_key *key) { /* @@ -142,15 +147,14 @@ bool futex_private_hash_get(struct futex_private_hash= *fph) { if (fph->immutable) return true; - return rcuref_get(&fph->users); + return futex_ref_get(fph); } =20 void futex_private_hash_put(struct futex_private_hash *fph) { - /* Ignore return value, last put is verified via rcuref_is_dead() */ if (fph->immutable) return; - if (rcuref_put(&fph->users)) + if (futex_ref_put(fph)) wake_up_var(fph->mm); } =20 @@ -243,14 +247,18 @@ static bool __futex_pivot_hash(struct mm_struct *mm, fph =3D rcu_dereference_protected(mm->futex_phash, lockdep_is_held(&mm->futex_hash_lock)); if (fph) { - if (!rcuref_is_dead(&fph->users)) { + if (!futex_ref_is_dead(fph)) { mm->futex_phash_new =3D new; return false; } =20 futex_rehash_private(fph, new); } - rcu_assign_pointer(mm->futex_phash, new); + new->state =3D FR_PERCPU; + scoped_guard(rcu) { + mm->futex_batches =3D get_state_synchronize_rcu(); + rcu_assign_pointer(mm->futex_phash, new); + } kvfree_rcu(fph, rcu); return true; } @@ -289,9 +297,7 @@ struct futex_private_hash *futex_private_hash(void) if (!fph) return NULL; =20 - if (fph->immutable) - return fph; - if (rcuref_get(&fph->users)) + if (futex_private_hash_get(fph)) return fph; } futex_pivot_hash(mm); @@ -1527,16 +1533,219 @@ static void futex_hash_bucket_init(struct futex_ha= sh_bucket *fhb, #define FH_IMMUTABLE 0x02 =20 #ifdef CONFIG_FUTEX_PRIVATE_HASH + +/* + * futex-ref + * + * Heavily inspired by percpu-rwsem/percpu-refcount; not reusing any of th= at + * code because it just doesn't fit right. + * + * Dual counter, per-cpu / atomic approach like percpu-refcount, except it + * re-initializes the state automatically, such that the fph swizzle is al= so a + * transition back to per-cpu. + */ + +static void futex_ref_rcu(struct rcu_head *head); + +static void __futex_ref_atomic_begin(struct futex_private_hash *fph) +{ + struct mm_struct *mm =3D fph->mm; + + /* + * The counter we're about to switch to must have fully switched; + * otherwise it would be impossible for it to have reported success + * from futex_ref_is_dead(). + */ + WARN_ON_ONCE(atomic_long_read(&mm->futex_atomic) !=3D 0); + + /* + * Set the atomic to the bias value such that futex_ref_{get,put}() + * will never observe 0. Will be fixed up in __futex_ref_atomic_end() + * when folding in the percpu count. + */ + atomic_long_set(&mm->futex_atomic, LONG_MAX); + smp_store_release(&fph->state, FR_ATOMIC); + + call_rcu_hurry(&mm->futex_rcu, futex_ref_rcu); +} + +static void __futex_ref_atomic_end(struct futex_private_hash *fph) +{ + struct mm_struct *mm =3D fph->mm; + unsigned int count =3D 0; + long ret; + int cpu; + + /* + * Per __futex_ref_atomic_begin() the state of the fph must be ATOMIC + * and per this RCU callback, everybody must now observe this state and + * use the atomic variable. + */ + WARN_ON_ONCE(fph->state !=3D FR_ATOMIC); + + /* + * Therefore the per-cpu counter is now stable, sum and reset. + */ + for_each_possible_cpu(cpu) { + unsigned int *ptr =3D per_cpu_ptr(mm->futex_ref, cpu); + count +=3D *ptr; + *ptr =3D 0; + } + + /* + * Re-init for the next cycle. + */ + this_cpu_inc(*mm->futex_ref); /* 0 -> 1 */ + + /* + * Add actual count, subtract bias and initial refcount. + * + * The moment this atomic operation happens, futex_ref_is_dead() can + * become true. + */ + ret =3D atomic_long_add_return(count - LONG_MAX - 1, &mm->futex_atomic); + if (!ret) + wake_up_var(mm); + + WARN_ON_ONCE(ret < 0); + mmput_async(mm); +} + +static void futex_ref_rcu(struct rcu_head *head) +{ + struct mm_struct *mm =3D container_of(head, struct mm_struct, futex_rcu); + struct futex_private_hash *fph =3D rcu_dereference_raw(mm->futex_phash); + + if (fph->state =3D=3D FR_PERCPU) { + /* + * Per this extra grace-period, everybody must now observe + * fph as the current fph and no previously observed fph's + * are in-flight. + * + * Notably, nobody will now rely on the atomic + * futex_ref_is_dead() state anymore so we can begin the + * migration of the per-cpu counter into the atomic. + */ + __futex_ref_atomic_begin(fph); + return; + } + + __futex_ref_atomic_end(fph); +} + +/* + * Drop the initial refcount and transition to atomics. + */ +static void futex_ref_drop(struct futex_private_hash *fph) +{ + struct mm_struct *mm =3D fph->mm; + + /* + * Can only transition the current fph; + */ + WARN_ON_ONCE(rcu_dereference_raw(mm->futex_phash) !=3D fph); + /* + * We enqueue at least one RCU callback. Ensure mm stays if the task + * exits before the transition is completed. + */ + mmget(mm); + + /* + * In order to avoid the following scenario: + * + * futex_hash() __futex_pivot_hash() + * guard(rcu); guard(mm->futex_hash_lock); + * fph =3D mm->futex_phash; + * rcu_assign_pointer(&mm->futex_phash, new); + * futex_hash_allocate() + * futex_ref_drop() + * fph->state =3D FR_ATOMIC; + * atomic_set(, BIAS); + * + * futex_private_hash_get(fph); // OOPS + * + * Where an old fph (which is FR_ATOMIC) and should fail on + * inc_not_zero, will succeed because a new transition is started and + * the atomic is bias'ed away from 0. + * + * There must be at least one full grace-period between publishing a + * new fph and trying to replace it. + */ + if (poll_state_synchronize_rcu(mm->futex_batches)) { + /* + * There was a grace-period, we can begin now. + */ + __futex_ref_atomic_begin(fph); + return; + } + + call_rcu_hurry(&mm->futex_rcu, futex_ref_rcu); +} + +static bool futex_ref_get(struct futex_private_hash *fph) +{ + struct mm_struct *mm =3D fph->mm; + + guard(rcu)(); + + if (smp_load_acquire(&fph->state) =3D=3D FR_PERCPU) { + this_cpu_inc(*mm->futex_ref); + return true; + } + + return atomic_long_inc_not_zero(&mm->futex_atomic); +} + +static bool futex_ref_put(struct futex_private_hash *fph) +{ + struct mm_struct *mm =3D fph->mm; + + guard(rcu)(); + + if (smp_load_acquire(&fph->state) =3D=3D FR_PERCPU) { + this_cpu_dec(*mm->futex_ref); + return false; + } + + return atomic_long_dec_and_test(&mm->futex_atomic); +} + +static bool futex_ref_is_dead(struct futex_private_hash *fph) +{ + struct mm_struct *mm =3D fph->mm; + + guard(rcu)(); + + if (smp_load_acquire(&fph->state) =3D=3D FR_PERCPU) + return false; + + return atomic_long_read(&mm->futex_atomic) =3D=3D 0; +} + +int futex_mm_init(struct mm_struct *mm) +{ + mutex_init(&mm->futex_hash_lock); + RCU_INIT_POINTER(mm->futex_phash, NULL); + mm->futex_phash_new =3D NULL; + /* futex-ref */ + atomic_long_set(&mm->futex_atomic, 0); + mm->futex_batches =3D get_state_synchronize_rcu(); + mm->futex_ref =3D alloc_percpu(unsigned int); + if (!mm->futex_ref) + return -ENOMEM; + this_cpu_inc(*mm->futex_ref); /* 0 -> 1 */ + return 0; +} + void futex_hash_free(struct mm_struct *mm) { struct futex_private_hash *fph; =20 + free_percpu(mm->futex_ref); kvfree(mm->futex_phash_new); fph =3D rcu_dereference_raw(mm->futex_phash); - if (fph) { - WARN_ON_ONCE(rcuref_read(&fph->users) > 1); + if (fph) kvfree(fph); - } } =20 static bool futex_pivot_pending(struct mm_struct *mm) @@ -1549,7 +1758,7 @@ static bool futex_pivot_pending(struct mm_struct *mm) return true; =20 fph =3D rcu_dereference(mm->futex_phash); - return rcuref_is_dead(&fph->users); + return futex_ref_is_dead(fph); } =20 static bool futex_hash_less(struct futex_private_hash *a, @@ -1598,11 +1807,11 @@ static int futex_hash_allocate(unsigned int hash_sl= ots, unsigned int flags) } } =20 - fph =3D kvzalloc(struct_size(fph, queues, hash_slots), GFP_KERNEL_ACCOUNT= | __GFP_NOWARN); + fph =3D kvzalloc(struct_size(fph, queues, hash_slots), + GFP_KERNEL_ACCOUNT | __GFP_NOWARN); if (!fph) return -ENOMEM; =20 - rcuref_init(&fph->users, 1); fph->hash_mask =3D hash_slots ? hash_slots - 1 : 0; fph->custom =3D custom; fph->immutable =3D !!(flags & FH_IMMUTABLE); @@ -1645,7 +1854,7 @@ static int futex_hash_allocate(unsigned int hash_slot= s, unsigned int flags) * allocated a replacement hash, drop the initial * reference on the existing hash. */ - futex_private_hash_put(cur); + futex_ref_drop(cur); } =20 if (new) { --=20 2.50.0 From nobody Tue Oct 7 10:32:56 2025 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 71BC32E612B for ; Thu, 10 Jul 2025 11:00:21 +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=1752145224; cv=none; b=EKe/6xRpr6P246ggeQsX0w2XwpfqaB1QQsv/d9+dqzcL/5a/BoesBcWOjMf9BA1tLj5esVyaQc8KN8/jKuPaQoKcYUbcvb+uQ8wDpbArttTbkiOKsjCcAHjUTe7G+2olszSe/648MEF4IbnvAvsyzGZKgRQ6ZZbRJFjM+S+TAm4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752145224; c=relaxed/simple; bh=s6jWx3Ex1yAyBoRqDEmWyRcOriaDM0svhfJKXBjf6to=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g0nGrFUSJFAL1WEz7NvwhilsZntCkNnqCn8E39DISD8BZyjvXD4JsrXFtckmYsZspH3MVgRHiYNx6NnemQwT0Ot1vN2McF9KMPiC/8Uz4/yKop6iSIaXwHUmBxlPr6SxbU1kyT54undE86FnqN0jCuJghFFlxw7lWV/+HFAzQPY= 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=xjEHAozQ; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=WP2XrRDZ; 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="xjEHAozQ"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="WP2XrRDZ" From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752145219; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=blSukIN3CoYZ/Bhr2rxv9xJ99pcqaxJAXiP83jewurM=; b=xjEHAozQ4GkiFgvheajjqN4vsaekaSVnO85YmGLn3F0vPG4NXP6FuGYP3HzeOCxpYOUdYd /Kt2bLJ1eSGu/OyIe+PTXs1CjdH9VkWw6iJBbLHAlPvTVqbumrPO29bTl8kthwGZH/l9o2 AbYqUPm033wN3MDbixFlZJS4bNH1ZQb7vBrFA7vjFu+1x3VmOCLLsreM+eqX24gDAgbxUk 5ywd1tA2RA/ukTzIqWdswnYeohTDohfa5ElAIVHtsh7gocDCTGCUy0Ltkf9Wi8sQ0zZT0d MjYi8/fWWA9y0CIBZmFNQnigwMHMtwEePqobIaE+jubXenev/+58pcY+U6VWmQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752145219; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=blSukIN3CoYZ/Bhr2rxv9xJ99pcqaxJAXiP83jewurM=; b=WP2XrRDZcq/C01sJM08/rK2KpK8ysJ6QD1k35qPTpX7heKL6Zm7ClTiHDDihudRHjkQMyP mC6gsTOHgfiVwpDg== To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Andr=C3=A9=20Almeida?= , Darren Hart , Davidlohr Bueso , Ingo Molnar , Juri Lelli , Peter Zijlstra , Thomas Gleixner , Valentin Schneider , Waiman Long , Sebastian Andrzej Siewior Subject: [PATCH v2 3/6] futex: Make futex_private_hash_get() static Date: Thu, 10 Jul 2025 13:00:08 +0200 Message-ID: <20250710110011.384614-4-bigeasy@linutronix.de> In-Reply-To: <20250710110011.384614-1-bigeasy@linutronix.de> References: <20250710110011.384614-1-bigeasy@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" futex_private_hash_get() is not used outside if its compilation unit. Make it static. Signed-off-by: Sebastian Andrzej Siewior --- kernel/futex/core.c | 2 +- kernel/futex/futex.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/futex/core.c b/kernel/futex/core.c index 1dcb4c8a2585d..1981574a459d5 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -143,7 +143,7 @@ static inline bool futex_key_is_private(union futex_key= *key) return !(key->both.offset & (FUT_OFF_INODE | FUT_OFF_MMSHARED)); } =20 -bool futex_private_hash_get(struct futex_private_hash *fph) +static bool futex_private_hash_get(struct futex_private_hash *fph) { if (fph->immutable) return true; diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h index fcd1617212eed..c74eac572acd7 100644 --- a/kernel/futex/futex.h +++ b/kernel/futex/futex.h @@ -228,14 +228,12 @@ extern void futex_hash_get(struct futex_hash_bucket *= hb); extern void futex_hash_put(struct futex_hash_bucket *hb); =20 extern struct futex_private_hash *futex_private_hash(void); -extern bool futex_private_hash_get(struct futex_private_hash *fph); extern void futex_private_hash_put(struct futex_private_hash *fph); =20 #else /* !CONFIG_FUTEX_PRIVATE_HASH */ static inline void futex_hash_get(struct futex_hash_bucket *hb) { } static inline void futex_hash_put(struct futex_hash_bucket *hb) { } static inline struct futex_private_hash *futex_private_hash(void) { return= NULL; } -static inline bool futex_private_hash_get(void) { return false; } static inline void futex_private_hash_put(struct futex_private_hash *fph) = { } #endif =20 --=20 2.50.0 From nobody Tue Oct 7 10:32:56 2025 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 71B202E6122 for ; Thu, 10 Jul 2025 11:00:22 +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=1752145224; cv=none; b=bawQsOhnzylLNjwAOoq13bwWUtemDrN+2MpnJxadZ1NuBfgJpvFTzPMHW7cqywd059vr5c4ufu4GZoSzqykXABbTuGxCL8IhRCqKZjzHWulNpI8ulxE6yfxcygK99aH12h8Yv5vMfxki6XeakLtqlfmrNTmAHPu8n5r7l4IUiR4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752145224; c=relaxed/simple; bh=2JB2xgvJ7VqhxKwXaxp9lQ9EPS6UzCrzIlxS0TeU8G0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nQ5SfnM7ENPysSIJYLPTrzJo1tdQOJqviSuyqivGaq5zqm0FBn0qItM+fBXqD1t5GFtuLzXdyxA3vsJPMdeQmrfQPbRxxOaoaquqPMHrFyB8ZzDNMuxyNmwgIjAcc+8kumlUQJFXWKrTWjwP64Ofs9ICZZS5LMXbIRacaISx03w= 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=GCz3wxg6; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=fGMuwvcb; 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="GCz3wxg6"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="fGMuwvcb" From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752145220; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HdUl88rznqHl5m+a4vcX9da19I7kSaXVW1otRUuqpt8=; b=GCz3wxg6as4JuZ6xk+nxH20PIl3ubKhUt6oBmHhD6cLzzB2yYK9iM5DIqUSAryrtsiouoj 9LNMilknizMA0VLfidGQjvjWy0T2HiipOIAS5mq/3+Xia+pdl0nSZj+TVQuICidVWTkhGH Qf178sMuIMnwyZI2ouOAq7uiGUBVJK5yl6FxTVIJ5C2CFFlTzLa5Q0oGLTllOWGtR/BFcm ytL/mvPKP1XE5wNa5CXhSE4xaQSgZxqwk1X0yw3eYsju8reLrd9yX0gEhy+2IqthIiibii S5Ersf5FcbRxVOuth0C3GZUGIo6uhUQfa3Vq9sVTNy2n7M3koChKK+mnJyqmuA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752145220; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HdUl88rznqHl5m+a4vcX9da19I7kSaXVW1otRUuqpt8=; b=fGMuwvcbve0W9FE1TT8lvubAAzE41JnVcpIrXwnC1wE/5pBuZmuAHq5EnknzrWooyX7VA6 aSKPzUE0czI6SVAQ== To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Andr=C3=A9=20Almeida?= , Darren Hart , Davidlohr Bueso , Ingo Molnar , Juri Lelli , Peter Zijlstra , Thomas Gleixner , Valentin Schneider , Waiman Long , Sebastian Andrzej Siewior Subject: [PATCH v2 4/6] futex: Remove support for IMMUTABLE Date: Thu, 10 Jul 2025 13:00:09 +0200 Message-ID: <20250710110011.384614-5-bigeasy@linutronix.de> In-Reply-To: <20250710110011.384614-1-bigeasy@linutronix.de> References: <20250710110011.384614-1-bigeasy@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The FH_FLAG_IMMUTABLE flag was meant to avoid the reference counting on the private hash and so to avoid the performance regression on big machines. With the switch to per-CPU counter this is no longer needed. That flag was never useable on any released kernel. Remove any support for IMMUTABLE while preserve the flags argument and enforce it to be zero. Signed-off-by: Sebastian Andrzej Siewior --- include/uapi/linux/prctl.h | 2 -- kernel/futex/core.c | 36 +++--------------------------------- 2 files changed, 3 insertions(+), 35 deletions(-) diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index 43dec6eed559a..3b93fb906e3c5 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -367,8 +367,6 @@ struct prctl_mm_map { /* FUTEX hash management */ #define PR_FUTEX_HASH 78 # define PR_FUTEX_HASH_SET_SLOTS 1 -# define FH_FLAG_IMMUTABLE (1ULL << 0) # define PR_FUTEX_HASH_GET_SLOTS 2 -# define PR_FUTEX_HASH_GET_IMMUTABLE 3 =20 #endif /* _LINUX_PRCTL_H */ diff --git a/kernel/futex/core.c b/kernel/futex/core.c index 1981574a459d5..d9bb5567af0c5 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -69,7 +69,6 @@ struct futex_private_hash { struct rcu_head rcu; void *mm; bool custom; - bool immutable; struct futex_hash_bucket queues[]; }; =20 @@ -145,15 +144,11 @@ static inline bool futex_key_is_private(union futex_k= ey *key) =20 static bool futex_private_hash_get(struct futex_private_hash *fph) { - if (fph->immutable) - return true; return futex_ref_get(fph); } =20 void futex_private_hash_put(struct futex_private_hash *fph) { - if (fph->immutable) - return; if (futex_ref_put(fph)) wake_up_var(fph->mm); } @@ -1530,7 +1525,6 @@ static void futex_hash_bucket_init(struct futex_hash_= bucket *fhb, } =20 #define FH_CUSTOM 0x01 -#define FH_IMMUTABLE 0x02 =20 #ifdef CONFIG_FUTEX_PRIVATE_HASH =20 @@ -1800,7 +1794,7 @@ static int futex_hash_allocate(unsigned int hash_slot= s, unsigned int flags) */ scoped_guard(rcu) { fph =3D rcu_dereference(mm->futex_phash); - if (fph && (!fph->hash_mask || fph->immutable)) { + if (fph && !fph->hash_mask) { if (custom) return -EBUSY; return 0; @@ -1814,7 +1808,6 @@ static int futex_hash_allocate(unsigned int hash_slot= s, unsigned int flags) =20 fph->hash_mask =3D hash_slots ? hash_slots - 1 : 0; fph->custom =3D custom; - fph->immutable =3D !!(flags & FH_IMMUTABLE); fph->mm =3D mm; =20 for (i =3D 0; i < hash_slots; i++) @@ -1838,7 +1831,7 @@ static int futex_hash_allocate(unsigned int hash_slot= s, unsigned int flags) mm->futex_phash_new =3D NULL; =20 if (fph) { - if (cur && (!cur->hash_mask || cur->immutable)) { + if (cur && !cur->hash_mask) { /* * If two threads simultaneously request the global * hash then the first one performs the switch, @@ -1931,19 +1924,6 @@ static int futex_hash_get_slots(void) return 0; } =20 -static int futex_hash_get_immutable(void) -{ - struct futex_private_hash *fph; - - guard(rcu)(); - fph =3D rcu_dereference(current->mm->futex_phash); - if (fph && fph->immutable) - return 1; - if (fph && !fph->hash_mask) - return 1; - return 0; -} - #else =20 static int futex_hash_allocate(unsigned int hash_slots, unsigned int flags) @@ -1956,10 +1936,6 @@ static int futex_hash_get_slots(void) return 0; } =20 -static int futex_hash_get_immutable(void) -{ - return 0; -} #endif =20 int futex_hash_prctl(unsigned long arg2, unsigned long arg3, unsigned long= arg4) @@ -1969,10 +1945,8 @@ int futex_hash_prctl(unsigned long arg2, unsigned lo= ng arg3, unsigned long arg4) =20 switch (arg2) { case PR_FUTEX_HASH_SET_SLOTS: - if (arg4 & ~FH_FLAG_IMMUTABLE) + if (arg4) return -EINVAL; - if (arg4 & FH_FLAG_IMMUTABLE) - flags |=3D FH_IMMUTABLE; ret =3D futex_hash_allocate(arg3, flags); break; =20 @@ -1980,10 +1954,6 @@ int futex_hash_prctl(unsigned long arg2, unsigned lo= ng arg3, unsigned long arg4) ret =3D futex_hash_get_slots(); break; =20 - case PR_FUTEX_HASH_GET_IMMUTABLE: - ret =3D futex_hash_get_immutable(); - break; - default: ret =3D -EINVAL; break; --=20 2.50.0 From nobody Tue Oct 7 10:32:56 2025 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 F2C7C2E62C4 for ; Thu, 10 Jul 2025 11:00:22 +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=1752145225; cv=none; b=VkfteS3mF/m5OmrJ4dEXv3IWN+cUt99uf00AD9cIk/ftRqVdoU6zINbs3cA4nxP54/Vc0yQ0XSYuiCY8XAhIDeQW9h7RDdRaRq3hwR1EJpP5VwHJsd924IIdIcZFJ9lG2A8vDBxfKAnioFv2HtB0OwV2845sLAv/ZR/cr0HY+T8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752145225; c=relaxed/simple; bh=e4ieNbDVNJ0oF2cnKbpogHX+yYl740cXCeM2pfaBda8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PA8FOTxGLjjeCQtc71o/iOPHDZhIoCwwkxrFhvUR6zmIPheW3Pz2+wEOZM5aNPVy3aSQXg4b7l9t3JqN4psvAZQl8yufgoA8qaEIT/xVztpYEpksX0kN7R2fPijz0n9vQ3fC6e8SAjJU0wGKNU/KNlPbCrt9mEMdOMM2/TePFEM= 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=2R43D/Sc; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=XonZpfzO; 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="2R43D/Sc"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="XonZpfzO" From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752145221; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Pfg2x8ebG/45Q4P97HTsPAZQeWvS2FnAOtMP+WryIsU=; b=2R43D/ScYNzfDoNLCQwiLy3moy0z6yIU3CpZaoOfIfRIaSUvQBbKxOKlgC+xRSgXbzY++R ubKrTvnII2ae0fSxxGt7c6CYGdYM4pxbtCoNwyHIP4m4ReJ4LofO4Lx94jEwWZOoD1cjOb alI5+CYkhjG4QsVA8LIjpD4wT5lfbB8TOvOqi3W0TRwoqIkcD8e1ptDmvuSx1SAmTRglI/ a9rn5D0DTv41gmDSwcZmz0rKppQp9sSgTSoAXQ5WszTuMYMauV9RcxVuZKisbp3mU4lChB fMxKK2Wnxi5z9L//D9U7tja3GZJl28yMxB3/UA0KgbmCcETACOs6TeMYOY1XSA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752145221; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Pfg2x8ebG/45Q4P97HTsPAZQeWvS2FnAOtMP+WryIsU=; b=XonZpfzODvg33RjJXhMQlvxGCnmHjz5eoncmw1g7UnyyC9w24ApxEIqrM1sXf5dfiOu5tX XnQqFEyL2yP4cWBw== To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Andr=C3=A9=20Almeida?= , Darren Hart , Davidlohr Bueso , Ingo Molnar , Juri Lelli , Peter Zijlstra , Thomas Gleixner , Valentin Schneider , Waiman Long , Sebastian Andrzej Siewior Subject: [PATCH v2 5/6] selftests/futex: Remove support for IMMUTABLE Date: Thu, 10 Jul 2025 13:00:10 +0200 Message-ID: <20250710110011.384614-6-bigeasy@linutronix.de> In-Reply-To: <20250710110011.384614-1-bigeasy@linutronix.de> References: <20250710110011.384614-1-bigeasy@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Testing for the IMMUTABLE part of the futex interface is not needed after the removal of the interface. Remove support for IMMUTABLE from the sefltest. Signed-off-by: Sebastian Andrzej Siewior --- .../futex/functional/futex_priv_hash.c | 71 ++++++------------- 1 file changed, 22 insertions(+), 49 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 625e3be4129c3..a9cedc365102e 100644 --- a/tools/testing/selftests/futex/functional/futex_priv_hash.c +++ b/tools/testing/selftests/futex/functional/futex_priv_hash.c @@ -26,14 +26,12 @@ static int counter; #ifndef PR_FUTEX_HASH #define PR_FUTEX_HASH 78 # define PR_FUTEX_HASH_SET_SLOTS 1 -# define FH_FLAG_IMMUTABLE (1ULL << 0) # define PR_FUTEX_HASH_GET_SLOTS 2 -# define PR_FUTEX_HASH_GET_IMMUTABLE 3 #endif =20 -static int futex_hash_slots_set(unsigned int slots, int flags) +static int futex_hash_slots_set(unsigned int slots) { - return prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS, slots, flags); + return prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS, slots, 0); } =20 static int futex_hash_slots_get(void) @@ -41,16 +39,11 @@ static int futex_hash_slots_get(void) return prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_GET_SLOTS); } =20 -static int futex_hash_immutable_get(void) -{ - return prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_GET_IMMUTABLE); -} - static void futex_hash_slots_set_verify(int slots) { int ret; =20 - ret =3D futex_hash_slots_set(slots, 0); + 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(); @@ -64,13 +57,13 @@ static void futex_hash_slots_set_verify(int slots) ksft_test_result_pass("SET and GET slots %d passed\n", slots); } =20 -static void futex_hash_slots_set_must_fail(int slots, int flags) +static void futex_hash_slots_set_must_fail(int slots) { int ret; =20 - ret =3D futex_hash_slots_set(slots, flags); - ksft_test_result(ret < 0, "futex_hash_slots_set(%d, %d)\n", - slots, flags); + ret =3D futex_hash_slots_set(slots); + ksft_test_result(ret < 0, "futex_hash_slots_set(%d)\n", + slots); } =20 static void *thread_return_fn(void *arg) @@ -152,18 +145,14 @@ int main(int argc, char *argv[]) { int futex_slots1, futex_slotsn, online_cpus; pthread_mutexattr_t mutex_attr_pi; - int use_global_hash =3D 0; int ret, retry =3D 20; int c; =20 - while ((c =3D getopt(argc, argv, "cghv:")) !=3D -1) { + while ((c =3D getopt(argc, argv, "chv:")) !=3D -1) { switch (c) { case 'c': log_color(1); break; - case 'g': - use_global_hash =3D 1; - break; case 'h': usage(basename(argv[0])); exit(0); @@ -178,7 +167,7 @@ int main(int argc, char *argv[]) } =20 ksft_print_header(); - ksft_set_plan(22); + ksft_set_plan(21); =20 ret =3D pthread_mutexattr_init(&mutex_attr_pi); ret |=3D pthread_mutexattr_setprotocol(&mutex_attr_pi, PTHREAD_PRIO_INHER= IT); @@ -191,10 +180,6 @@ int main(int argc, char *argv[]) if (ret !=3D 0) ksft_exit_fail_msg("futex_hash_slots_get() failed: %d, %m\n", ret); =20 - ret =3D futex_hash_immutable_get(); - if (ret !=3D 0) - ksft_exit_fail_msg("futex_hash_immutable_get() failed: %d, %m\n", ret); - 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) @@ -267,7 +252,7 @@ int main(int argc, char *argv[]) futex_hash_slots_set_verify(32); futex_hash_slots_set_verify(16); =20 - ret =3D futex_hash_slots_set(15, 0); + ret =3D futex_hash_slots_set(15); ksft_test_result(ret < 0, "Use 15 slots\n"); =20 futex_hash_slots_set_verify(2); @@ -285,28 +270,23 @@ int main(int argc, char *argv[]) ksft_test_result(ret =3D=3D 2, "No more auto-resize after manaul setting,= got %d\n", ret); =20 - futex_hash_slots_set_must_fail(1 << 29, 0); + futex_hash_slots_set_must_fail(1 << 29); + futex_hash_slots_set_verify(4); =20 /* - * Once the private hash has been made immutable or global hash has been = requested, - * then this requested can not be undone. + * Once the global hash has been requested, then this requested can not + * be undone. */ - if (use_global_hash) { - ret =3D futex_hash_slots_set(0, 0); - ksft_test_result(ret =3D=3D 0, "Global hash request\n"); - } else { - ret =3D futex_hash_slots_set(4, FH_FLAG_IMMUTABLE); - ksft_test_result(ret =3D=3D 0, "Immutable resize to 4\n"); - } + ret =3D futex_hash_slots_set(0); + ksft_test_result(ret =3D=3D 0, "Global hash request\n"); if (ret !=3D 0) goto out; =20 - futex_hash_slots_set_must_fail(4, 0); - futex_hash_slots_set_must_fail(4, FH_FLAG_IMMUTABLE); - futex_hash_slots_set_must_fail(8, 0); - futex_hash_slots_set_must_fail(8, FH_FLAG_IMMUTABLE); - futex_hash_slots_set_must_fail(0, FH_FLAG_IMMUTABLE); - futex_hash_slots_set_must_fail(6, FH_FLAG_IMMUTABLE); + 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); =20 ret =3D pthread_barrier_init(&barrier_main, NULL, MAX_THREADS); if (ret !=3D 0) { @@ -317,14 +297,7 @@ int main(int argc, char *argv[]) join_max_threads(); =20 ret =3D futex_hash_slots_get(); - if (use_global_hash) { - ksft_test_result(ret =3D=3D 0, "Continue to use global hash\n"); - } else { - ksft_test_result(ret =3D=3D 4, "Continue to use the 4 hash buckets\n"); - } - - ret =3D futex_hash_immutable_get(); - ksft_test_result(ret =3D=3D 1, "Hash reports to be immutable\n"); + ksft_test_result(ret =3D=3D 0, "Continue to use global hash\n"); =20 out: ksft_finished(); --=20 2.50.0 From nobody Tue Oct 7 10:32:56 2025 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 F1C372E6D33; Thu, 10 Jul 2025 11:00:23 +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=1752145225; cv=none; b=LJFEKO28uEGLVyFlUwZsOmsh4EcoJbOS3h5dP6oLkDDyODGh66GZmalIh7xxIMIm5JlZpxvWIA7hQynB59m0uypSnINC9StxQtiFAvUWlgg2I1ugF+FHKoJ3m67HYG391De+l+5sH4TlUtwaksIboxK/IvdN/OXp9xmsOrXfyoM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752145225; c=relaxed/simple; bh=VMVrky7aEFXB1dsuXoZKTUr/9FXsjEpD11b0L6/8koo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BqpfiK34w62aMM76enNFY4IM2hSdXz6ikU3fjnqFkF9QIYIV8ZgqGcsUTVFbO67QIw7zg4+g3SAVtcZyg19vOr7mtPCKYu+eRkVSIVR2OH2fWXb7VxCsNVglzmEFk5ZfFR9GyDNGVV1YqwaRzveFNqZtBLGBQYcxfsDngrHbisc= 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=k9NMBjNI; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=o1IrUWpI; 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="k9NMBjNI"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="o1IrUWpI" From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1752145221; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LXOx5tAvnAjtoJdjEyryVJUnZ+UnzqrMm9Wls9voAK0=; b=k9NMBjNIoPXUZSO6UXx2XkTapOSLDJ65Qj+jO6gR9sUj+IAaNm0XIZfule8s0RrPkdeNw1 hYtIo3KT/aUd4ZKnGtx1F3VfxCgekO73sHA4tJADcYSb6+1XS9gpaAG8j/Ouy9Mdb8RjnF ab0VVgVFbNFlOAhG/1WFDLEYTdxS8afkMVuOMgZI+0D43j1VJvc4+kip3YCLPU18uB6E4+ VF88VfkrF5gAq9fYjXyjuGHGaFFeQIxq78FUSUABh/T4nbwa2iuyX0KHQPp9ImkM7X3HDK 30UxsCmOdAKqxYqcJWTOC7BjECQW6H2BxOKD7IQk94WVTpMH6EiPrxASi7jgDA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1752145221; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LXOx5tAvnAjtoJdjEyryVJUnZ+UnzqrMm9Wls9voAK0=; b=o1IrUWpIBNW/LmaOcvkFndWUL6YYKWXZTgTcaV5GAadPM+bM9uVQjH+UNUlaLu1BuyQ8M9 6Ky28uP4SfdMLgAA== To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Andr=C3=A9=20Almeida?= , Darren Hart , Davidlohr Bueso , Ingo Molnar , Juri Lelli , Peter Zijlstra , Thomas Gleixner , Valentin Schneider , Waiman Long , Sebastian Andrzej Siewior , "Liang, Kan" , Adrian Hunter , Alexander Shishkin , Arnaldo Carvalho de Melo , Ian Rogers , Jiri Olsa , Mark Rutland , Namhyung Kim , linux-perf-users@vger.kernel.org Subject: [PATCH v2 6/6] perf bench futex: Remove support for IMMUTABLE Date: Thu, 10 Jul 2025 13:00:11 +0200 Message-ID: <20250710110011.384614-7-bigeasy@linutronix.de> In-Reply-To: <20250710110011.384614-1-bigeasy@linutronix.de> References: <20250710110011.384614-1-bigeasy@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" It has been decided to remove the support IMMUTABLE futex. perf bench was one of the eary users for testing purposes. Now that the API is removed before it could be used in an official release, remove the bits from perf, too. Remove Remove support for IMMUTABLE futex. Cc: "Liang, Kan" Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Ian Rogers Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: linux-perf-users@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior --- tools/include/uapi/linux/prctl.h | 2 -- tools/perf/bench/futex-hash.c | 1 - tools/perf/bench/futex-lock-pi.c | 1 - tools/perf/bench/futex-requeue.c | 1 - tools/perf/bench/futex-wake-parallel.c | 1 - tools/perf/bench/futex-wake.c | 1 - tools/perf/bench/futex.c | 21 +++++-------------- tools/perf/bench/futex.h | 1 - .../trace/beauty/include/uapi/linux/prctl.h | 2 -- 9 files changed, 5 insertions(+), 26 deletions(-) diff --git a/tools/include/uapi/linux/prctl.h b/tools/include/uapi/linux/pr= ctl.h index 43dec6eed559a..3b93fb906e3c5 100644 --- a/tools/include/uapi/linux/prctl.h +++ b/tools/include/uapi/linux/prctl.h @@ -367,8 +367,6 @@ struct prctl_mm_map { /* FUTEX hash management */ #define PR_FUTEX_HASH 78 # define PR_FUTEX_HASH_SET_SLOTS 1 -# define FH_FLAG_IMMUTABLE (1ULL << 0) # define PR_FUTEX_HASH_GET_SLOTS 2 -# define PR_FUTEX_HASH_GET_IMMUTABLE 3 =20 #endif /* _LINUX_PRCTL_H */ diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index d2d6d7f3ea331..7e29f04da7449 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -56,7 +56,6 @@ static struct bench_futex_parameters params =3D { =20 static const struct option options[] =3D { OPT_INTEGER( 'b', "buckets", ¶ms.nbuckets, "Specify amount of hash bu= ckets"), - OPT_BOOLEAN( 'I', "immutable", ¶ms.buckets_immutable, "Make the hash = buckets immutable"), OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of threads= "), OPT_UINTEGER('r', "runtime", ¶ms.runtime, "Specify runtime (in second= s)"), OPT_UINTEGER('f', "futexes", ¶ms.nfutexes, "Specify amount of futexes= per threads"), diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock= -pi.c index 5144a158512cc..40640b6744279 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -47,7 +47,6 @@ static struct bench_futex_parameters params =3D { =20 static const struct option options[] =3D { OPT_INTEGER( 'b', "buckets", ¶ms.nbuckets, "Specify amount of hash bu= ckets"), - OPT_BOOLEAN( 'I', "immutable", ¶ms.buckets_immutable, "Make the hash = buckets immutable"), OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of threads= "), OPT_UINTEGER('r', "runtime", ¶ms.runtime, "Specify runtime (in second= s)"), OPT_BOOLEAN( 'M', "multi", ¶ms.multi, "Use multiple futexes"), diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requ= eue.c index a2f91ee1950b3..0748b0fd689e8 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -52,7 +52,6 @@ static struct bench_futex_parameters params =3D { =20 static const struct option options[] =3D { OPT_INTEGER( 'b', "buckets", ¶ms.nbuckets, "Specify amount of hash bu= ckets"), - OPT_BOOLEAN( 'I', "immutable", ¶ms.buckets_immutable, "Make the hash = buckets immutable"), OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of thread= s"), OPT_UINTEGER('q', "nrequeue", ¶ms.nrequeue, "Specify amount of thread= s to requeue at once"), OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not displa= y data/details"), diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/fute= x-wake-parallel.c index ee66482c29fd1..6aede7c46b337 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -63,7 +63,6 @@ static struct bench_futex_parameters params =3D { =20 static const struct option options[] =3D { OPT_INTEGER( 'b', "buckets", ¶ms.nbuckets, "Specify amount of hash bu= ckets"), - OPT_BOOLEAN( 'I', "immutable", ¶ms.buckets_immutable, "Make the hash = buckets immutable"), OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of threads= "), OPT_UINTEGER('w', "nwakers", ¶ms.nwakes, "Specify amount of waking th= reads"), OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display= data/details"), diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 8d6107f7cd941..a31fc1563862e 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -52,7 +52,6 @@ static struct bench_futex_parameters params =3D { =20 static const struct option options[] =3D { OPT_INTEGER( 'b', "buckets", ¶ms.nbuckets, "Specify amount of hash bu= ckets"), - OPT_BOOLEAN( 'I', "immutable", ¶ms.buckets_immutable, "Make the hash = buckets immutable"), OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of threads= "), OPT_UINTEGER('w', "nwakes", ¶ms.nwakes, "Specify amount of threads t= o wake at once"), OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display= data/details"), diff --git a/tools/perf/bench/futex.c b/tools/perf/bench/futex.c index 4c4fee107e591..1481196a22f0c 100644 --- a/tools/perf/bench/futex.c +++ b/tools/perf/bench/futex.c @@ -9,21 +9,17 @@ #ifndef PR_FUTEX_HASH #define PR_FUTEX_HASH 78 # define PR_FUTEX_HASH_SET_SLOTS 1 -# define FH_FLAG_IMMUTABLE (1ULL << 0) # define PR_FUTEX_HASH_GET_SLOTS 2 -# define PR_FUTEX_HASH_GET_IMMUTABLE 3 #endif // PR_FUTEX_HASH =20 void futex_set_nbuckets_param(struct bench_futex_parameters *params) { - unsigned long flags; int ret; =20 if (params->nbuckets < 0) return; =20 - flags =3D params->buckets_immutable ? FH_FLAG_IMMUTABLE : 0; - ret =3D prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS, params->nbuckets, f= lags); + ret =3D prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_SET_SLOTS, params->nbuckets, 0= ); if (ret) { printf("Requesting %d hash buckets failed: %d/%m\n", params->nbuckets, ret); @@ -47,18 +43,11 @@ void futex_print_nbuckets(struct bench_futex_parameters= *params) printf("Requested: %d in usage: %d\n", params->nbuckets, ret); err(EXIT_FAILURE, "prctl(PR_FUTEX_HASH)"); } - if (params->nbuckets =3D=3D 0) { + if (params->nbuckets =3D=3D 0) ret =3D asprintf(&futex_hash_mode, "Futex hashing: global hash"); - } else { - ret =3D prctl(PR_FUTEX_HASH, PR_FUTEX_HASH_GET_IMMUTABLE); - if (ret < 0) { - printf("Can't check if the hash is immutable: %m\n"); - err(EXIT_FAILURE, "prctl(PR_FUTEX_HASH)"); - } - ret =3D asprintf(&futex_hash_mode, "Futex hashing: %d hash buckets %s", - params->nbuckets, - ret =3D=3D 1 ? "(immutable)" : ""); - } + else + ret =3D asprintf(&futex_hash_mode, "Futex hashing: %d hash buckets", + params->nbuckets); } else { if (ret <=3D 0) { ret =3D asprintf(&futex_hash_mode, "Futex hashing: global hash"); diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h index 9c9a73f9d865e..dd295d27044ac 100644 --- a/tools/perf/bench/futex.h +++ b/tools/perf/bench/futex.h @@ -26,7 +26,6 @@ struct bench_futex_parameters { unsigned int nwakes; unsigned int nrequeue; int nbuckets; - bool buckets_immutable; }; =20 /** diff --git a/tools/perf/trace/beauty/include/uapi/linux/prctl.h b/tools/per= f/trace/beauty/include/uapi/linux/prctl.h index 43dec6eed559a..3b93fb906e3c5 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/prctl.h +++ b/tools/perf/trace/beauty/include/uapi/linux/prctl.h @@ -367,8 +367,6 @@ struct prctl_mm_map { /* FUTEX hash management */ #define PR_FUTEX_HASH 78 # define PR_FUTEX_HASH_SET_SLOTS 1 -# define FH_FLAG_IMMUTABLE (1ULL << 0) # define PR_FUTEX_HASH_GET_SLOTS 2 -# define PR_FUTEX_HASH_GET_IMMUTABLE 3 =20 #endif /* _LINUX_PRCTL_H */ --=20 2.50.0