[PATCH v9 11/11] futex: Use a hashmask instead of hashsize.

Sebastian Andrzej Siewior posted 11 patches 9 months, 3 weeks ago
[PATCH v9 11/11] futex: Use a hashmask instead of hashsize.
Posted by Sebastian Andrzej Siewior 9 months, 3 weeks ago
The global hash uses futex_hashsize to save the amount of the hash
buckets that have been allocated during system boot. On each
futex_hash() invocation this number is substracted by one to get the
mask. This can be optimized by saving directly the mask avoiding the
substraction on each futex_hash() invocation.

Rename futex_hashsize to futex_hashmask and save the mask of the
allocated hash map.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 kernel/futex/core.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index 6d375b9407c85..283e6644c05f9 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -52,10 +52,10 @@
  */
 static struct {
 	struct futex_hash_bucket *queues;
-	unsigned long            hashsize;
+	unsigned long            hashmask;
 } __futex_data __read_mostly __aligned(2*sizeof(long));
 #define futex_queues   (__futex_data.queues)
-#define futex_hashsize (__futex_data.hashsize)
+#define futex_hashmask (__futex_data.hashmask)
 
 struct futex_private_hash {
 	rcuref_t	users;
@@ -285,7 +285,7 @@ struct futex_hash_bucket *__futex_hash(union futex_key *key)
 	hash = jhash2((u32 *)key,
 		      offsetof(typeof(*key), both.offset) / 4,
 		      key->both.offset);
-	return &futex_queues[hash & (futex_hashsize - 1)];
+	return &futex_queues[hash & futex_hashmask];
 }
 
 #ifndef CONFIG_BASE_SMALL
@@ -1420,8 +1420,8 @@ static int futex_hash_allocate(unsigned int hash_slots)
 		hash_slots = 16;
 	if (hash_slots < 2)
 		hash_slots = 2;
-	if (hash_slots > futex_hashsize)
-		hash_slots = futex_hashsize;
+	if (hash_slots > futex_hashmask + 1)
+		hash_slots = futex_hashmask + 1;
 	if (!is_power_of_2(hash_slots))
 		hash_slots = rounddown_pow_of_two(hash_slots);
 
@@ -1482,7 +1482,7 @@ int futex_hash_allocate_default(void)
 	 */
 	buckets = roundup_pow_of_two(4 * threads);
 	buckets = max(buckets, 16);
-	buckets = min(buckets, futex_hashsize);
+	buckets = min(buckets, futex_hashmask + 1);
 
 	if (current_buckets >= buckets)
 		return 0;
@@ -1536,24 +1536,25 @@ int futex_hash_prctl(unsigned long arg2, unsigned long arg3)
 
 static int __init futex_init(void)
 {
+	unsigned long i, hashsize;
 	unsigned int futex_shift;
-	unsigned long i;
 
 #ifdef CONFIG_BASE_SMALL
-	futex_hashsize = 16;
+	hashsize = 16;
 #else
-	futex_hashsize = roundup_pow_of_two(256 * num_possible_cpus());
+	hashsize = roundup_pow_of_two(256 * num_possible_cpus());
 #endif
 
 	futex_queues = alloc_large_system_hash("futex", sizeof(*futex_queues),
-					       futex_hashsize, 0, 0,
+					       hashsize, 0, 0,
 					       &futex_shift, NULL,
-					       futex_hashsize, futex_hashsize);
-	futex_hashsize = 1UL << futex_shift;
+					       hashsize, hashsize);
+	hashsize = 1UL << futex_shift;
 
-	for (i = 0; i < futex_hashsize; i++)
+	for (i = 0; i < hashsize; i++)
 		futex_hash_bucket_init(&futex_queues[i], 0);
 
+	futex_hashmask = hashsize - 1;
 	return 0;
 }
 core_initcall(futex_init);
-- 
2.47.2
Re: [PATCH v9 11/11] futex: Use a hashmask instead of hashsize.
Posted by Thomas Gleixner 9 months, 3 weeks ago
On Tue, Feb 25 2025 at 18:09, Sebastian Andrzej Siewior wrote:
> The global hash uses futex_hashsize to save the amount of the hash
> buckets that have been allocated during system boot. On each
> futex_hash() invocation this number is substracted by one to get the
> mask. This can be optimized by saving directly the mask avoiding the
> substraction on each futex_hash() invocation.

As this is true independent of the private hash muck, this should go to
the top of the series, so it can be applied right away. Aside of that it
spares the churn in the new code ....

Thanks,

        tglx