Re: [PATCH v5 8/8] futex: Use runtime constants for __futex_hash() hot path

From: Sebastian Andrzej Siewior

Date: Wed Jul 01 2026 - 15:59:12 EST


On 2026-06-30 04:55:31 [+0000], K Prateek Nayak wrote:
> --- a/kernel/futex/core.c
> +++ b/kernel/futex/core.c
> @@ -395,13 +391,13 @@ __futex_hash(union futex_key *key, struct futex_private_hash *fph, struct futex_
> * NOTE: this isn't perfectly uniform, but it is fast and
> * handles sparse node masks.
> */
> - node = (hash >> futex_hashshift) % nr_node_ids;
> + node = runtime_const_shift_right_32(hash, __futex_shift) % nr_node_ids;
> if (!node_possible(node)) {
> node = find_next_bit_wrap(node_possible_map.bits, nr_node_ids, node);
> }

I replaced this with:

diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index 79e770d4d166..30d8622958d2 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -382,6 +382,7 @@ __futex_hash(union futex_key *key, struct futex_private_hash *fph, struct futex_
key->both.offset);

if (node == FUTEX_NO_NODE) {
+ u32 node_limit = nr_node_ids;
/*
* In case of !FLAGS_NUMA, use some unused hash bits to pick a
* node -- this ensures regular futexes are interleaved across
@@ -391,9 +392,9 @@ __futex_hash(union futex_key *key, struct futex_private_hash *fph, struct futex_
* NOTE: this isn't perfectly uniform, but it is fast and
* handles sparse node masks.
*/
- node = runtime_const_shift_right_32(hash, __futex_shift) % nr_node_ids;
- if (!node_possible(node)) {
- node = find_next_bit_wrap(node_possible_map.bits, nr_node_ids, node);
+ node = reciprocal_scale(hash, node_limit);
+ if (!node_possible(node)) {
+ node = find_next_bit_wrap(node_possible_map.bits, node_limit, node);
}
}

I don't think it is worse, I hardly see a change perf wise. Sometimes
op/s is reported almost unchanged, sometimes it improves a bit.

What it does it reads nr_node_ids only once (which has no effect here
because I have no sparse node) and it replaces the shift + divl with
imulq + shift.

perf was pointing me to the divl but now it points to the imulq.
¯\_(ツ)_/¯

But having that div gone, can't be bad, can it?

Sebastian