From: "André Almeida" <andrealmeid@igalia.com>
To: Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
linux-kernel@vger.kernel.org
Cc: Darren Hart <dvhart@infradead.org>,
Davidlohr Bueso <dave@stgolabs.net>,
Ingo Molnar <mingo@redhat.com>,
Juri Lelli <juri.lelli@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Thomas Gleixner <tglx@linutronix.de>,
Valentin Schneider <vschneid@redhat.com>,
Waiman Long <longman@redhat.com>
Subject: Re: [PATCH v12 14/21] futex: Allow to resize the private local hash
Date: Thu, 8 May 2025 17:32:24 -0300 [thread overview]
Message-ID: <986dcbc0-0505-496a-ae75-e0c1bd7c2725@igalia.com> (raw)
In-Reply-To: <20250416162921.513656-15-bigeasy@linutronix.de>
Em 16/04/2025 13:29, Sebastian Andrzej Siewior escreveu:
> The mm_struct::futex_hash_lock guards the futex_hash_bucket assignment/
> replacement. The futex_hash_allocate()/ PR_FUTEX_HASH_SET_SLOTS
> operation can now be invoked at runtime and resize an already existing
> internal private futex_hash_bucket to another size.
>
> The reallocation is based on an idea by Thomas Gleixner: The initial
> allocation of struct futex_private_hash sets the reference count
> to one. Every user acquires a reference on the local hash before using
> it and drops it after it enqueued itself on the hash bucket. There is no
> reference held while the task is scheduled out while waiting for the
> wake up.
> The resize process allocates a new struct futex_private_hash and drops
> the initial reference. Synchronized with mm_struct::futex_hash_lock it
> is checked if the reference counter for the currently used
> mm_struct::futex_phash is marked as DEAD. If so, then all users enqueued
> on the current private hash are requeued on the new private hash and the
> new private hash is set to mm_struct::futex_phash. Otherwise the newly
> allocated private hash is saved as mm_struct::futex_phash_new and the
> rehashing and reassigning is delayed to the futex_hash() caller once the
> reference counter is marked DEAD.
> The replacement is not performed at rcuref_put() time because certain
> callers, such as futex_wait_queue(), drop their reference after changing
> the task state. This change will be destroyed once the futex_hash_lock
> is acquired.
>
> The user can change the number slots with PR_FUTEX_HASH_SET_SLOTS
> multiple times. An increase and decrease is allowed and request blocks
> until the assignment is done.
>
> The private hash allocated at thread creation is changed from 16 to
> 16 <= 4 * number_of_threads <= global_hash_size
> where number_of_threads can not exceed the number of online CPUs. Should
> the user PR_FUTEX_HASH_SET_SLOTS then the auto scaling is disabled.
>
> [peterz: reorganize the code to avoid state tracking and simplify new
> object handling, block the user until changes are in effect, allow
> increase and decrease of the hash].
>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
> include/linux/futex.h | 3 +-
> include/linux/mm_types.h | 4 +-
> kernel/futex/core.c | 290 ++++++++++++++++++++++++++++++++++++---
> kernel/futex/requeue.c | 5 +
> 4 files changed, 281 insertions(+), 21 deletions(-)
>
[...]
> static int futex_hash_allocate(unsigned int hash_slots, bool custom)
> @@ -1273,16 +1442,23 @@ static int futex_hash_allocate(unsigned int hash_slots, bool custom)
> if (hash_slots && (hash_slots == 1 || !is_power_of_2(hash_slots)))
> return -EINVAL;
>
> - if (mm->futex_phash)
> - return -EALREADY;
> -
> - if (!thread_group_empty(current))
> - return -EINVAL;
> + /*
> + * Once we've disabled the global hash there is no way back.
> + */
> + scoped_guard(rcu) {
> + fph = rcu_dereference(mm->futex_phash);
> + if (fph && !fph->hash_mask) {
> + if (custom)
> + return -EBUSY;
> + return 0;
> + }
> + }
>
> fph = kvzalloc(struct_size(fph, queues, hash_slots), GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
> if (!fph)
> return -ENOMEM;
>
> + rcuref_init(&fph->users, 1);
> fph->hash_mask = hash_slots ? hash_slots - 1 : 0;
> fph->custom = custom;
> fph->mm = mm;
> @@ -1290,26 +1466,102 @@ static int futex_hash_allocate(unsigned int hash_slots, bool custom)
> for (i = 0; i < hash_slots; i++)
> futex_hash_bucket_init(&fph->queues[i], fph);
>
> - mm->futex_phash = fph;
If (hash_slots == 0), do we still need to do all of this work bellow? I
thought that using the global hash would allow to skip this.
> + if (custom) {
> + /*
> + * Only let prctl() wait / retry; don't unduly delay clone().
> + */
> +again:
> + wait_var_event(mm, futex_pivot_pending(mm));
> + }
> +
> + scoped_guard(mutex, &mm->futex_hash_lock) {
> + struct futex_private_hash *free __free(kvfree) = NULL;
> + struct futex_private_hash *cur, *new;
> +
> + cur = rcu_dereference_protected(mm->futex_phash,
> + lockdep_is_held(&mm->futex_hash_lock));
> + new = mm->futex_phash_new;
> + mm->futex_phash_new = NULL;
> +
> + if (fph) {
> + if (cur && !new) {
> + /*
> + * If we have an existing hash, but do not yet have
> + * allocated a replacement hash, drop the initial
> + * reference on the existing hash.
> + */
> + futex_private_hash_put(cur);
> + }
> +
> + if (new) {
> + /*
> + * Two updates raced; throw out the lesser one.
> + */
> + if (futex_hash_less(new, fph)) {
> + free = new;
> + new = fph;
> + } else {
> + free = fph;
> + }
> + } else {
> + new = fph;
> + }
> + fph = NULL;
> + }
> +
> + if (new) {
> + /*
> + * Will set mm->futex_phash_new on failure;
> + * futex_private_hash_get() will try again.
> + */
> + if (!__futex_pivot_hash(mm, new) && custom)
> + goto again;
Is it safe to use a goto inside a scoped_guard(){}?
next prev parent reply other threads:[~2025-05-08 20:32 UTC|newest]
Thread overview: 109+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-16 16:29 [PATCH v12 00/21] futex: Add support task local hash maps, FUTEX2_NUMA and FUTEX2_MPOL Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 01/21] rcuref: Provide rcuref_is_dead() Sebastian Andrzej Siewior
2025-05-05 21:09 ` André Almeida
2025-05-08 10:34 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 02/21] mm: Add vmalloc_huge_node() Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Peter Zijlstra
2025-04-16 16:29 ` [PATCH v12 03/21] futex: Move futex_queue() into futex_wait_setup() Sebastian Andrzej Siewior
2025-05-05 21:43 ` André Almeida
2025-05-16 12:53 ` Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Peter Zijlstra
2025-04-16 16:29 ` [PATCH v12 04/21] futex: Pull futex_hash() out of futex_q_lock() Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Peter Zijlstra
2025-04-16 16:29 ` [PATCH v12 05/21] futex: Create hb scopes Sebastian Andrzej Siewior
2025-05-06 23:45 ` André Almeida
2025-05-16 12:20 ` Sebastian Andrzej Siewior
2025-05-16 13:23 ` Peter Zijlstra
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Peter Zijlstra
2025-04-16 16:29 ` [PATCH v12 06/21] futex: Create futex_hash() get/put class Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Peter Zijlstra
2025-04-16 16:29 ` [PATCH v12 07/21] futex: Create private_hash() " Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Peter Zijlstra
2025-04-16 16:29 ` [PATCH v12 08/21] futex: Acquire a hash reference in futex_wait_multiple_setup() Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 09/21] futex: Decrease the waiter count before the unlock operation Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 10/21] futex: Introduce futex_q_lockptr_lock() Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-05-08 19:06 ` [PATCH v12 10/21] " André Almeida
2025-05-16 12:18 ` Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 11/21] futex: Create helper function to initialize a hash slot Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 12/21] futex: Add basic infrastructure for local task local hash Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 13/21] futex: Allow automatic allocation of process wide futex hash Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 14/21] futex: Allow to resize the private local hash Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-05-08 20:32 ` André Almeida [this message]
2025-05-16 10:49 ` [PATCH v12 14/21] " Sebastian Andrzej Siewior
2025-05-16 13:00 ` André Almeida
2025-05-10 8:45 ` [PATCH] futex: Fix futex_mm_init() build failure on older compilers, remove rcu_assign_pointer() Ingo Molnar
2025-05-11 8:11 ` [tip: locking/futex] futex: Relax the rcu_assign_pointer() assignment of mm->futex_phash in futex_mm_init() tip-bot2 for Ingo Molnar
2025-06-01 7:39 ` [PATCH v12 14/21] futex: Allow to resize the private local hash Lai, Yi
2025-06-02 11:00 ` Sebastian Andrzej Siewior
2025-06-02 14:36 ` Lai, Yi
2025-06-02 14:44 ` Sebastian Andrzej Siewior
2025-06-02 15:00 ` Lai, Yi
2025-06-11 9:20 ` [tip: locking/urgent] " tip-bot2 for Sebastian Andrzej Siewior
2025-06-11 14:39 ` tip-bot2 for Sebastian Andrzej Siewior
2025-06-11 14:43 ` Sebastian Andrzej Siewior
2025-06-11 15:11 ` Peter Zijlstra
2025-06-11 15:20 ` Peter Zijlstra
2025-06-11 15:35 ` Sebastian Andrzej Siewior
2025-06-16 17:14 ` Calvin Owens
2025-06-17 7:16 ` Sebastian Andrzej Siewior
2025-06-17 9:23 ` Calvin Owens
2025-06-17 9:50 ` Sebastian Andrzej Siewior
2025-06-17 16:11 ` Calvin Owens
2025-06-18 2:15 ` Calvin Owens
2025-06-18 16:47 ` Sebastian Andrzej Siewior
2025-06-18 16:03 ` Sebastian Andrzej Siewior
2025-06-18 16:49 ` Calvin Owens
2025-06-18 17:09 ` Sebastian Andrzej Siewior
2025-06-18 20:56 ` Calvin Owens
2025-06-18 22:47 ` Calvin Owens
2025-06-19 21:07 ` Calvin Owens
2025-06-20 10:31 ` Sebastian Andrzej Siewior
2025-06-20 18:56 ` Calvin Owens
2025-06-21 1:02 ` Calvin Owens
2025-06-21 7:24 ` Calvin Owens
2025-06-21 21:01 ` Sebastian Andrzej Siewior
2025-06-22 16:17 ` Calvin Owens
2025-04-16 16:29 ` [PATCH v12 15/21] futex: Allow to make the private hash immutable Sebastian Andrzej Siewior
2025-05-02 18:01 ` Peter Zijlstra
2025-05-05 7:14 ` Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 16/21] futex: Implement FUTEX2_NUMA Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Peter Zijlstra
2025-04-16 16:29 ` [PATCH v12 17/21] futex: Implement FUTEX2_MPOL Sebastian Andrzej Siewior
2025-05-02 18:45 ` Peter Zijlstra
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Peter Zijlstra
2025-04-16 16:29 ` [PATCH v12 18/21] tools headers: Synchronize prctl.h ABI header Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 19/21] tools/perf: Allow to select the number of hash buckets Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 20/21] selftests/futex: Add futex_priv_hash Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-05-09 21:22 ` [PATCH v12 20/21] " André Almeida
2025-05-16 7:38 ` Sebastian Andrzej Siewior
2025-05-27 11:28 ` Mark Brown
2025-05-27 12:23 ` Sebastian Andrzej Siewior
2025-05-27 12:35 ` Mark Brown
2025-05-27 12:43 ` Sebastian Andrzej Siewior
2025-05-27 12:59 ` Mark Brown
2025-05-27 13:25 ` Sebastian Andrzej Siewior
2025-05-27 13:40 ` Mark Brown
2025-05-27 13:45 ` Sebastian Andrzej Siewior
2025-04-16 16:29 ` [PATCH v12 21/21] selftests/futex: Add futex_numa_mpol Sebastian Andrzej Siewior
2025-05-02 19:08 ` Peter Zijlstra
2025-05-05 7:33 ` Sebastian Andrzej Siewior
2025-05-02 19:16 ` Peter Zijlstra
2025-05-05 7:36 ` Sebastian Andrzej Siewior
2025-05-08 10:33 ` [tip: locking/futex] " tip-bot2 for Sebastian Andrzej Siewior
2025-04-16 16:31 ` [PATCH v12 00/21] futex: Add support task local hash maps, FUTEX2_NUMA and FUTEX2_MPOL Sebastian Andrzej Siewior
2025-05-02 19:48 ` Peter Zijlstra
2025-05-03 10:09 ` Peter Zijlstra
2025-05-05 7:30 ` Sebastian Andrzej Siewior
2025-05-06 7:36 ` Peter Zijlstra
2025-05-09 11:41 ` Sebastian Andrzej Siewior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=986dcbc0-0505-496a-ae75-e0c1bd7c2725@igalia.com \
--to=andrealmeid@igalia.com \
--cc=bigeasy@linutronix.de \
--cc=dave@stgolabs.net \
--cc=dvhart@infradead.org \
--cc=juri.lelli@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=vschneid@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®