[PATCH v11 00/19] futex: Add support task local hash maps, FUTEX2_NUMA and FUTEX2_MPOL

Sebastian Andrzej Siewior posted 19 patches 10 months ago
There is a newer version of this series
include/linux/futex.h                  |  36 +-
include/linux/mm_types.h               |   7 +-
include/linux/mmap_lock.h              |   4 +
include/linux/rcuref.h                 |  22 +-
include/linux/vmalloc.h                |   9 +-
include/uapi/linux/futex.h             |  10 +-
include/uapi/linux/prctl.h             |   6 +
init/Kconfig                           |  10 +
io_uring/futex.c                       |   4 +-
kernel/fork.c                          |  24 +
kernel/futex/core.c                    | 794 ++++++++++++++++++++++---
kernel/futex/futex.h                   |  73 ++-
kernel/futex/pi.c                      | 300 +++++-----
kernel/futex/requeue.c                 | 480 +++++++--------
kernel/futex/waitwake.c                | 201 ++++---
kernel/sys.c                           |   4 +
mm/nommu.c                             |  18 +-
mm/vmalloc.c                           |  11 +-
tools/include/uapi/linux/prctl.h       |  44 +-
tools/perf/bench/Build                 |   1 +
tools/perf/bench/futex-hash.c          |   7 +
tools/perf/bench/futex-lock-pi.c       |   5 +
tools/perf/bench/futex-requeue.c       |   6 +
tools/perf/bench/futex-wake-parallel.c |   9 +-
tools/perf/bench/futex-wake.c          |   4 +
tools/perf/bench/futex.c               |  60 ++
tools/perf/bench/futex.h               |   5 +
27 files changed, 1585 insertions(+), 569 deletions(-)
create mode 100644 tools/perf/bench/futex.c
[PATCH v11 00/19] futex: Add support task local hash maps, FUTEX2_NUMA and FUTEX2_MPOL
Posted by Sebastian Andrzej Siewior 10 months ago
this is a follow up on
        https://lore.kernel.org/ZwVOMgBMxrw7BU9A@jlelli-thinkpadt14gen4.remote.csb

and adds support for task local futex_hash_bucket.

This is the local hash map series with PeterZ FUTEX2_NUMA and
FUTEX2_MPOL plus a few fixes on top.

The complete tree is at
        https://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/staging.git/log/?h=futex_local_v11
        https://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/staging.git futex_local_v11

v10…v11: https://lore.kernel.org/all/20250312151634.2183278-1-bigeasy@linutronix.de
  - PeterZ' fixups, changes to the local hash series have been folded
    into the earlier patches so things are not added and renamed later
    and the functionality is changed.

  - vmalloc_huge() has been implemented on top of vmalloc_huge_node()
    and the NOMMU bots have been adjusted. akpm asked for this.

  - wake_up_var() has been removed from __futex_pivot_hash(). It is
    enough to wake the userspace waiter after the final put so it can
    perform the resize itself.

  - Changed to logic in futex_pivot_pending() so it does not block for
    the user. It waits for __futex_pivot_hash() which follows the logic
    in __futex_pivot_hash().

  - Updated kernel doc for __futex_hash().

  - Patches 17+ are new:
    - Wire up PR_FUTEX_HASH_SET_SLOTS in "perf bench futex"
    - Add "immutable" mode to PR_FUTEX_HASH_SET_SLOTS to avoid resizing
      the local hash any further. This avoids rcuref usage which is
      noticeable in "perf bench futex hash"

Peter Zijlstra (8):
  mm: Add vmalloc_huge_node()
  futex: Move futex_queue() into futex_wait_setup()
  futex: Pull futex_hash() out of futex_q_lock()
  futex: Create hb scopes
  futex: Create futex_hash() get/put class
  futex: Create private_hash() get/put class
  futex: Implement FUTEX2_NUMA
  futex: Implement FUTEX2_MPOL

Sebastian Andrzej Siewior (11):
  rcuref: Provide rcuref_is_dead().
  futex: Acquire a hash reference in futex_wait_multiple_setup().
  futex: Decrease the waiter count before the unlock operation.
  futex: Introduce futex_q_lockptr_lock().
  futex: Create helper function to initialize a hash slot.
  futex: Add basic infrastructure for local task local hash.
  futex: Allow automatic allocation of process wide futex hash.
  futex: Allow to resize the private local hash.
  tools headers: Synchronize prctl.h ABI header
  tools/perf: Allow to select the number of hash buckets.
  futex: Allow to make the private hash immutable.

 include/linux/futex.h                  |  36 +-
 include/linux/mm_types.h               |   7 +-
 include/linux/mmap_lock.h              |   4 +
 include/linux/rcuref.h                 |  22 +-
 include/linux/vmalloc.h                |   9 +-
 include/uapi/linux/futex.h             |  10 +-
 include/uapi/linux/prctl.h             |   6 +
 init/Kconfig                           |  10 +
 io_uring/futex.c                       |   4 +-
 kernel/fork.c                          |  24 +
 kernel/futex/core.c                    | 794 ++++++++++++++++++++++---
 kernel/futex/futex.h                   |  73 ++-
 kernel/futex/pi.c                      | 300 +++++-----
 kernel/futex/requeue.c                 | 480 +++++++--------
 kernel/futex/waitwake.c                | 201 ++++---
 kernel/sys.c                           |   4 +
 mm/nommu.c                             |  18 +-
 mm/vmalloc.c                           |  11 +-
 tools/include/uapi/linux/prctl.h       |  44 +-
 tools/perf/bench/Build                 |   1 +
 tools/perf/bench/futex-hash.c          |   7 +
 tools/perf/bench/futex-lock-pi.c       |   5 +
 tools/perf/bench/futex-requeue.c       |   6 +
 tools/perf/bench/futex-wake-parallel.c |   9 +-
 tools/perf/bench/futex-wake.c          |   4 +
 tools/perf/bench/futex.c               |  60 ++
 tools/perf/bench/futex.h               |   5 +
 27 files changed, 1585 insertions(+), 569 deletions(-)
 create mode 100644 tools/perf/bench/futex.c

-- 
2.49.0
Re: [PATCH v11 00/19] futex: Add support task local hash maps, FUTEX2_NUMA and FUTEX2_MPOL
Posted by Sebastian Andrzej Siewior 10 months ago
On 2025-04-07 17:57:23 [+0200], To linux-kernel@vger.kernel.org wrote:
> This is the local hash map series with PeterZ FUTEX2_NUMA and
> FUTEX2_MPOL plus a few fixes on top.
…
> v10…v11: https://lore.kernel.org/all/20250312151634.2183278-1-bigeasy@linutronix.de
>   - PeterZ' fixups, changes to the local hash series have been folded
>     into the earlier patches so things are not added and renamed later
>     and the functionality is changed.

for easier comparison, here is a diff vs v10 excluding patches v17+

diff --git a/include/linux/futex.h b/include/linux/futex.h
index 19c37afa0432a..ee48dcfbfe59d 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -4,11 +4,11 @@
 
 #include <linux/sched.h>
 #include <linux/ktime.h>
+#include <linux/mm_types.h>
 
 #include <uapi/linux/futex.h>
 
 struct inode;
-struct mm_struct;
 struct task_struct;
 
 /*
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 09c3e3e33f1f8..de95794777ad6 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -168,12 +168,14 @@ void *__vmalloc_node_noprof(unsigned long size, unsigned long align, gfp_t gfp_m
 		int node, const void *caller) __alloc_size(1);
 #define __vmalloc_node(...)	alloc_hooks(__vmalloc_node_noprof(__VA_ARGS__))
 
-void *vmalloc_huge_noprof(unsigned long size, gfp_t gfp_mask) __alloc_size(1);
-#define vmalloc_huge(...)	alloc_hooks(vmalloc_huge_noprof(__VA_ARGS__))
-
 void *vmalloc_huge_node_noprof(unsigned long size, gfp_t gfp_mask, int node) __alloc_size(1);
 #define vmalloc_huge_node(...)	alloc_hooks(vmalloc_huge_node_noprof(__VA_ARGS__))
 
+static inline void *vmalloc_huge(unsigned long size, gfp_t gfp_mask)
+{
+	return vmalloc_huge_node(size, gfp_mask, NUMA_NO_NODE);
+}
+
 extern void *__vmalloc_array_noprof(size_t n, size_t size, gfp_t flags) __alloc_size(1, 2);
 #define __vmalloc_array(...)	alloc_hooks(__vmalloc_array_noprof(__VA_ARGS__))
 
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index 55b843644c51a..2344c1feaa4e3 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -354,7 +354,7 @@ struct prctl_mm_map {
 #define PR_LOCK_SHADOW_STACK_STATUS      76
 
 /* FUTEX hash management */
-#define PR_FUTEX_HASH			77
+#define PR_FUTEX_HASH			78
 # define PR_FUTEX_HASH_SET_SLOTS	1
 # define PR_FUTEX_HASH_GET_SLOTS	2
 
diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index 65523f3cfe32e..2f2a92c791def 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -124,6 +124,10 @@ late_initcall(fail_futex_debugfs);
 
 #endif /* CONFIG_FAIL_FUTEX */
 
+static struct futex_hash_bucket *
+__futex_hash(union futex_key *key, struct futex_private_hash *fph);
+
+#ifdef CONFIG_FUTEX_PRIVATE_HASH
 static inline bool futex_key_is_private(union futex_key *key)
 {
 	/*
@@ -133,10 +137,43 @@ static inline bool futex_key_is_private(union futex_key *key)
 	return !(key->both.offset & (FUT_OFF_INODE | FUT_OFF_MMSHARED));
 }
 
-static struct futex_hash_bucket *
-__futex_hash(union futex_key *key, struct futex_private_hash *fph);
+bool futex_private_hash_get(struct futex_private_hash *fph)
+{
+	return rcuref_get(&fph->users);
+}
+
+void futex_private_hash_put(struct futex_private_hash *fph)
+{
+	/* Ignore return value, last put is verified via rcuref_is_dead() */
+	if (rcuref_put(&fph->users))
+		wake_up_var(fph->mm);
+}
+
+/**
+ * futex_hash_get - Get an additional reference for the local hash.
+ * @hb:                    ptr to the private local hash.
+ *
+ * Obtain an additional reference for the already obtained hash bucket. The
+ * caller must already own an reference.
+ */
+void futex_hash_get(struct futex_hash_bucket *hb)
+{
+	struct futex_private_hash *fph = hb->priv;
+
+	if (!fph)
+		return;
+	WARN_ON_ONCE(!futex_private_hash_get(fph));
+}
+
+void futex_hash_put(struct futex_hash_bucket *hb)
+{
+	struct futex_private_hash *fph = hb->priv;
+
+	if (!fph)
+		return;
+	futex_private_hash_put(fph);
+}
 
-#ifdef CONFIG_FUTEX_PRIVATE_HASH
 static struct futex_hash_bucket *
 __futex_hash_private(union futex_key *key, struct futex_private_hash *fph)
 {
@@ -210,13 +247,12 @@ static bool __futex_pivot_hash(struct mm_struct *mm,
 	}
 	rcu_assign_pointer(mm->futex_phash, new);
 	kvfree_rcu(fph, rcu);
-	wake_up_var(mm);
 	return true;
 }
 
 static void futex_pivot_hash(struct mm_struct *mm)
 {
-	scoped_guard (mutex, &mm->futex_hash_lock) {
+	scoped_guard(mutex, &mm->futex_hash_lock) {
 		struct futex_private_hash *fph;
 
 		fph = mm->futex_phash_new;
@@ -255,28 +291,13 @@ struct futex_private_hash *futex_private_hash(void)
 	goto again;
 }
 
-bool futex_private_hash_get(struct futex_private_hash *fph)
-{
-	return rcuref_get(&fph->users);
-}
-
-void futex_private_hash_put(struct futex_private_hash *fph)
-{
-	/*
-	 * Ignore the result; the DEAD state is picked up
-	 * when rcuref_get() starts failing via rcuref_is_dead().
-	 */
-	if (rcuref_put(&fph->users))
-		wake_up_var(fph->mm);
-}
-
 struct futex_hash_bucket *futex_hash(union futex_key *key)
 {
 	struct futex_private_hash *fph;
 	struct futex_hash_bucket *hb;
 
 again:
-	scoped_guard (rcu) {
+	scoped_guard(rcu) {
 		hb = __futex_hash(key, NULL);
 		fph = hb->priv;
 
@@ -287,27 +308,9 @@ struct futex_hash_bucket *futex_hash(union futex_key *key)
 	goto again;
 }
 
-void futex_hash_get(struct futex_hash_bucket *hb)
-{
-	struct futex_private_hash *fph = hb->priv;
-
-	if (!fph)
-		return;
-	WARN_ON_ONCE(!futex_private_hash_get(fph));
-}
-
-void futex_hash_put(struct futex_hash_bucket *hb)
-{
-	struct futex_private_hash *fph = hb->priv;
-
-	if (!fph)
-		return;
-	futex_private_hash_put(fph);
-}
-
 #else /* !CONFIG_FUTEX_PRIVATE_HASH */
 
-static inline struct futex_hash_bucket *
+static struct futex_hash_bucket *
 __futex_hash_private(union futex_key *key, struct futex_private_hash *fph)
 {
 	return NULL;
@@ -388,12 +391,15 @@ static int futex_mpol(struct mm_struct *mm, unsigned long addr)
 #endif /* CONFIG_FUTEX_MPOL */
 
 /**
- * futex_hash - Return the hash bucket in the global hash
+ * __futex_hash - Return the hash bucket
  * @key:	Pointer to the futex key for which the hash is calculated
+ * @fph:	Pointer to private hash if known
  *
  * We hash on the keys returned from get_futex_key (see below) and return the
- * corresponding hash bucket in the global hash. If the FUTEX is private and
- * a local hash table is privated then this one is used.
+ * corresponding hash bucket.
+ * If the FUTEX is PROCESS_PRIVATE then a per-process hash bucket (from the
+ * private hash) is returned if existing. Otherwise a hash bucket from the
+ * global hash is returned.
  */
 static struct futex_hash_bucket *
 __futex_hash(union futex_key *key, struct futex_private_hash *fph)
@@ -1522,10 +1528,10 @@ static bool futex_pivot_pending(struct mm_struct *mm)
 	guard(rcu)();
 
 	if (!mm->futex_phash_new)
-		return false;
+		return true;
 
 	fph = rcu_dereference(mm->futex_phash);
-	return !rcuref_read(&fph->users);
+	return rcuref_is_dead(&fph->users);
 }
 
 static bool futex_hash_less(struct futex_private_hash *a,
@@ -1564,7 +1570,7 @@ static int futex_hash_allocate(unsigned int hash_slots, bool custom)
 	/*
 	 * Once we've disabled the global hash there is no way back.
 	 */
-	scoped_guard (rcu) {
+	scoped_guard(rcu) {
 		fph = rcu_dereference(mm->futex_phash);
 		if (fph && !fph->hash_mask) {
 			if (custom)
@@ -1631,7 +1637,7 @@ static int futex_hash_allocate(unsigned int hash_slots, bool custom)
 		if (new) {
 			/*
 			 * Will set mm->futex_phash_new on failure;
-			 * futex_get_private_hash() will try again.
+			 * futex_private_hash_get() will try again.
 			 */
 			if (!__futex_pivot_hash(mm, new) && custom)
 				goto again;
@@ -1681,7 +1687,7 @@ static int futex_hash_get_slots(void)
 
 	guard(rcu)();
 	fph = rcu_dereference(current->mm->futex_phash);
-	if (fph)
+	if (fph && fph->hash_mask)
 		return fph->hash_mask + 1;
 	return 0;
 }
diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h
index 52e9c0c4b6c87..004e4dbee4f93 100644
--- a/kernel/futex/futex.h
+++ b/kernel/futex/futex.h
@@ -222,7 +222,6 @@ futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout,
 		  int flags, u64 range_ns);
 
 extern struct futex_hash_bucket *futex_hash(union futex_key *key);
-
 #ifdef CONFIG_FUTEX_PRIVATE_HASH
 extern void futex_hash_get(struct futex_hash_bucket *hb);
 extern void futex_hash_put(struct futex_hash_bucket *hb);
@@ -234,15 +233,8 @@ extern void futex_private_hash_put(struct futex_private_hash *fph);
 #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(struct futex_private_hash *fph)
-{
-	return false;
-}
+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
 
diff --git a/kernel/futex/pi.c b/kernel/futex/pi.c
index 51c69e8808152..356e52c17d3c5 100644
--- a/kernel/futex/pi.c
+++ b/kernel/futex/pi.c
@@ -1042,7 +1042,7 @@ int futex_lock_pi(u32 __user *uaddr, unsigned int flags, ktime_t *time, int tryl
 cleanup:
 		/*
 		 * If we failed to acquire the lock (deadlock/signal/timeout), we must
-		 * must unwind the above, however we canont lock hb->lock because
+		 * unwind the above, however we canont lock hb->lock because
 		 * rt_mutex already has a waiter enqueued and hb->lock can itself try
 		 * and enqueue an rt_waiter through rtlock.
 		 *
diff --git a/kernel/futex/waitwake.c b/kernel/futex/waitwake.c
index 74647f6bf75de..bd8fef0f8d180 100644
--- a/kernel/futex/waitwake.c
+++ b/kernel/futex/waitwake.c
@@ -297,7 +297,7 @@ int futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
 		}
 
 		plist_for_each_entry_safe(this, next, &hb1->chain, list) {
-			if (futex_match (&this->key, &key1)) {
+			if (futex_match(&this->key, &key1)) {
 				if (this->pi_state || this->rt_waiter) {
 					ret = -EINVAL;
 					goto out_unlock;
@@ -311,7 +311,7 @@ int futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
 		if (op_ret > 0) {
 			op_ret = 0;
 			plist_for_each_entry_safe(this, next, &hb2->chain, list) {
-				if (futex_match (&this->key, &key2)) {
+				if (futex_match(&this->key, &key2)) {
 					if (this->pi_state || this->rt_waiter) {
 						ret = -EINVAL;
 						goto out_unlock;
@@ -385,7 +385,7 @@ int futex_unqueue_multiple(struct futex_vector *v, int count)
 }
 
 /**
- * __futex_wait_multiple_setup - Prepare to wait and enqueue multiple futexes
+ * futex_wait_multiple_setup - Prepare to wait and enqueue multiple futexes
  * @vs:		The futex list to wait on
  * @count:	The size of the list
  * @woken:	Index of the last woken futex, if any. Used to notify the
diff --git a/mm/nommu.c b/mm/nommu.c
index d04e601a8f4d7..aed58ea7398db 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -207,11 +207,22 @@ void *vmalloc_noprof(unsigned long size)
 }
 EXPORT_SYMBOL(vmalloc_noprof);
 
-void *vmalloc_huge_noprof(unsigned long size, gfp_t gfp_mask) __weak __alias(__vmalloc_noprof);
-
+/*
+ *	vmalloc_huge_node  -  allocate virtually contiguous memory, on a node
+ *
+ *	@size:		allocation size
+ *	@gfp_mask:	flags for the page level allocator
+ *	@node:          node to use for allocation or NUMA_NO_NODE
+ *
+ *	Allocate enough pages to cover @size from the page level
+ *	allocator and map them into contiguous kernel virtual space.
+ *
+ *	Due to NOMMU implications the node argument and HUGE page attribute is
+ *	ignored.
+ */
 void *vmalloc_huge_node_noprof(unsigned long size, gfp_t gfp_mask, int node)
 {
-	return vmalloc_huge_noprof(size, gfp_mask);
+	return __vmalloc_noprof(size, gfp_mask);
 }
 
 /*
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 69247b46413ca..0e2c49aaf84f1 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3947,9 +3947,10 @@ void *vmalloc_noprof(unsigned long size)
 EXPORT_SYMBOL(vmalloc_noprof);
 
 /**
- * vmalloc_huge - allocate virtually contiguous memory, allow huge pages
+ * vmalloc_huge_node - allocate virtually contiguous memory, allow huge pages
  * @size:      allocation size
  * @gfp_mask:  flags for the page level allocator
+ * @node:	    node to use for allocation or NUMA_NO_NODE
  *
  * Allocate enough pages to cover @size from the page level
  * allocator and map them into contiguous kernel virtual space.
@@ -3958,20 +3959,13 @@ EXPORT_SYMBOL(vmalloc_noprof);
  *
  * Return: pointer to the allocated memory or %NULL on error
  */
-void *vmalloc_huge_noprof(unsigned long size, gfp_t gfp_mask)
-{
-	return __vmalloc_node_range_noprof(size, 1, VMALLOC_START, VMALLOC_END,
-				    gfp_mask, PAGE_KERNEL, VM_ALLOW_HUGE_VMAP,
-				    NUMA_NO_NODE, __builtin_return_address(0));
-}
-EXPORT_SYMBOL_GPL(vmalloc_huge_noprof);
-
 void *vmalloc_huge_node_noprof(unsigned long size, gfp_t gfp_mask, int node)
 {
 	return __vmalloc_node_range_noprof(size, 1, VMALLOC_START, VMALLOC_END,
 					   gfp_mask, PAGE_KERNEL, VM_ALLOW_HUGE_VMAP,
 					   node, __builtin_return_address(0));
 }
+EXPORT_SYMBOL_GPL(vmalloc_huge_node_noprof);
 
 /**
  * vzalloc - allocate virtually contiguous memory with zero fill
Re: [PATCH v11 00/19] futex: Add support task local hash maps, FUTEX2_NUMA and FUTEX2_MPOL
Posted by Shrikanth Hegde 10 months ago

On 4/7/25 21:27, Sebastian Andrzej Siewior wrote:
> this is a follow up on
>          https://lore.kernel.org/ZwVOMgBMxrw7BU9A@jlelli-thinkpadt14gen4.remote.csb
> 
> and adds support for task local futex_hash_bucket.
> 
> This is the local hash map series with PeterZ FUTEX2_NUMA and
> FUTEX2_MPOL plus a few fixes on top.
> 
> The complete tree is at
>          https://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/staging.git/log/?h=futex_local_v11
>          https://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/staging.git futex_local_v11
> 
> v10…v11: https://lore.kernel.org/all/20250312151634.2183278-1-bigeasy@linutronix.de
>    - PeterZ' fixups, changes to the local hash series have been folded
>      into the earlier patches so things are not added and renamed later
>      and the functionality is changed.
> 
>    - vmalloc_huge() has been implemented on top of vmalloc_huge_node()
>      and the NOMMU bots have been adjusted. akpm asked for this.
> 
>    - wake_up_var() has been removed from __futex_pivot_hash(). It is
>      enough to wake the userspace waiter after the final put so it can
>      perform the resize itself.
> 
>    - Changed to logic in futex_pivot_pending() so it does not block for
>      the user. It waits for __futex_pivot_hash() which follows the logic
>      in __futex_pivot_hash().
> 
>    - Updated kernel doc for __futex_hash().


I don't see any change in Documentation/*. Is it updated in some
other path?

> 
>    - Patches 17+ are new:
>      - Wire up PR_FUTEX_HASH_SET_SLOTS in "perf bench futex"
>      - Add "immutable" mode to PR_FUTEX_HASH_SET_SLOTS to avoid resizing
>        the local hash any further. This avoids rcuref usage which is
>        noticeable in "perf bench futex hash"
> 
> Peter Zijlstra (8):
>    mm: Add vmalloc_huge_node()
>    futex: Move futex_queue() into futex_wait_setup()
>    futex: Pull futex_hash() out of futex_q_lock()
>    futex: Create hb scopes
>    futex: Create futex_hash() get/put class
>    futex: Create private_hash() get/put class
>    futex: Implement FUTEX2_NUMA
>    futex: Implement FUTEX2_MPOL
> 
> Sebastian Andrzej Siewior (11):
>    rcuref: Provide rcuref_is_dead().
>    futex: Acquire a hash reference in futex_wait_multiple_setup().
>    futex: Decrease the waiter count before the unlock operation.
>    futex: Introduce futex_q_lockptr_lock().
>    futex: Create helper function to initialize a hash slot.
>    futex: Add basic infrastructure for local task local hash.
>    futex: Allow automatic allocation of process wide futex hash.
>    futex: Allow to resize the private local hash.
>    tools headers: Synchronize prctl.h ABI header
>    tools/perf: Allow to select the number of hash buckets.
>    futex: Allow to make the private hash immutable.
> 
>   include/linux/futex.h                  |  36 +-
>   include/linux/mm_types.h               |   7 +-
>   include/linux/mmap_lock.h              |   4 +
>   include/linux/rcuref.h                 |  22 +-
>   include/linux/vmalloc.h                |   9 +-
>   include/uapi/linux/futex.h             |  10 +-
>   include/uapi/linux/prctl.h             |   6 +
>   init/Kconfig                           |  10 +
>   io_uring/futex.c                       |   4 +-
>   kernel/fork.c                          |  24 +
>   kernel/futex/core.c                    | 794 ++++++++++++++++++++++---
>   kernel/futex/futex.h                   |  73 ++-
>   kernel/futex/pi.c                      | 300 +++++-----
>   kernel/futex/requeue.c                 | 480 +++++++--------
>   kernel/futex/waitwake.c                | 201 ++++---
>   kernel/sys.c                           |   4 +
>   mm/nommu.c                             |  18 +-
>   mm/vmalloc.c                           |  11 +-
>   tools/include/uapi/linux/prctl.h       |  44 +-
>   tools/perf/bench/Build                 |   1 +
>   tools/perf/bench/futex-hash.c          |   7 +
>   tools/perf/bench/futex-lock-pi.c       |   5 +
>   tools/perf/bench/futex-requeue.c       |   6 +
>   tools/perf/bench/futex-wake-parallel.c |   9 +-
>   tools/perf/bench/futex-wake.c          |   4 +
>   tools/perf/bench/futex.c               |  60 ++
>   tools/perf/bench/futex.h               |   5 +
>   27 files changed, 1585 insertions(+), 569 deletions(-)
>   create mode 100644 tools/perf/bench/futex.c
> 

Re: [PATCH v11 00/19] futex: Add support task local hash maps, FUTEX2_NUMA and FUTEX2_MPOL
Posted by Sebastian Andrzej Siewior 9 months, 4 weeks ago
On 2025-04-10 23:21:49 [+0530], Shrikanth Hegde wrote:
> >    - Updated kernel doc for __futex_hash().
> 
> 
> I don't see any change in Documentation/*. Is it updated in some
> other path?

Look for "__futex_hash - Return" in
	https://lore.kernel.org/all/20250407160007.vOk8ijom@linutronix.de/

This is the change I refer to.

Sebastian
Re: [PATCH v11 00/19] futex: Add support task local hash maps, FUTEX2_NUMA and FUTEX2_MPOL
Posted by André Almeida 10 months ago
Hi Sebastian,

Thanks for your patchset. I think the perf support is great, but usually 
those new uAPI options should come with some selftests too.

Em 07/04/2025 12:57, Sebastian Andrzej Siewior escreveu:
> this is a follow up on
>          https://lore.kernel.org/ZwVOMgBMxrw7BU9A@jlelli-thinkpadt14gen4.remote.csb
> 
> and adds support for task local futex_hash_bucket.
> 
> This is the local hash map series with PeterZ FUTEX2_NUMA and
> FUTEX2_MPOL plus a few fixes on top.
> 
> The complete tree is at
>          https://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/staging.git/log/?h=futex_local_v11
>          https://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/staging.git futex_local_v11
> 
> v10…v11: https://lore.kernel.org/all/20250312151634.2183278-1-bigeasy@linutronix.de
>    - PeterZ' fixups, changes to the local hash series have been folded
>      into the earlier patches so things are not added and renamed later
>      and the functionality is changed.
> 
>    - vmalloc_huge() has been implemented on top of vmalloc_huge_node()
>      and the NOMMU bots have been adjusted. akpm asked for this.
> 
>    - wake_up_var() has been removed from __futex_pivot_hash(). It is
>      enough to wake the userspace waiter after the final put so it can
>      perform the resize itself.
> 
>    - Changed to logic in futex_pivot_pending() so it does not block for
>      the user. It waits for __futex_pivot_hash() which follows the logic
>      in __futex_pivot_hash().
> 
>    - Updated kernel doc for __futex_hash().
> 
>    - Patches 17+ are new:
>      - Wire up PR_FUTEX_HASH_SET_SLOTS in "perf bench futex"
>      - Add "immutable" mode to PR_FUTEX_HASH_SET_SLOTS to avoid resizing
>        the local hash any further. This avoids rcuref usage which is
>        noticeable in "perf bench futex hash"
> 
> Peter Zijlstra (8):
>    mm: Add vmalloc_huge_node()
>    futex: Move futex_queue() into futex_wait_setup()
>    futex: Pull futex_hash() out of futex_q_lock()
>    futex: Create hb scopes
>    futex: Create futex_hash() get/put class
>    futex: Create private_hash() get/put class
>    futex: Implement FUTEX2_NUMA
>    futex: Implement FUTEX2_MPOL
> 
> Sebastian Andrzej Siewior (11):
>    rcuref: Provide rcuref_is_dead().
>    futex: Acquire a hash reference in futex_wait_multiple_setup().
>    futex: Decrease the waiter count before the unlock operation.
>    futex: Introduce futex_q_lockptr_lock().
>    futex: Create helper function to initialize a hash slot.
>    futex: Add basic infrastructure for local task local hash.
>    futex: Allow automatic allocation of process wide futex hash.
>    futex: Allow to resize the private local hash.
>    tools headers: Synchronize prctl.h ABI header
>    tools/perf: Allow to select the number of hash buckets.
>    futex: Allow to make the private hash immutable.
> 
>   include/linux/futex.h                  |  36 +-
>   include/linux/mm_types.h               |   7 +-
>   include/linux/mmap_lock.h              |   4 +
>   include/linux/rcuref.h                 |  22 +-
>   include/linux/vmalloc.h                |   9 +-
>   include/uapi/linux/futex.h             |  10 +-
>   include/uapi/linux/prctl.h             |   6 +
>   init/Kconfig                           |  10 +
>   io_uring/futex.c                       |   4 +-
>   kernel/fork.c                          |  24 +
>   kernel/futex/core.c                    | 794 ++++++++++++++++++++++---
>   kernel/futex/futex.h                   |  73 ++-
>   kernel/futex/pi.c                      | 300 +++++-----
>   kernel/futex/requeue.c                 | 480 +++++++--------
>   kernel/futex/waitwake.c                | 201 ++++---
>   kernel/sys.c                           |   4 +
>   mm/nommu.c                             |  18 +-
>   mm/vmalloc.c                           |  11 +-
>   tools/include/uapi/linux/prctl.h       |  44 +-
>   tools/perf/bench/Build                 |   1 +
>   tools/perf/bench/futex-hash.c          |   7 +
>   tools/perf/bench/futex-lock-pi.c       |   5 +
>   tools/perf/bench/futex-requeue.c       |   6 +
>   tools/perf/bench/futex-wake-parallel.c |   9 +-
>   tools/perf/bench/futex-wake.c          |   4 +
>   tools/perf/bench/futex.c               |  60 ++
>   tools/perf/bench/futex.h               |   5 +
>   27 files changed, 1585 insertions(+), 569 deletions(-)
>   create mode 100644 tools/perf/bench/futex.c
> 

Re: [PATCH v11 00/19] futex: Add support task local hash maps, FUTEX2_NUMA and FUTEX2_MPOL
Posted by Sebastian Andrzej Siewior 10 months ago
On 2025-04-08 10:51:29 [-0300], André Almeida wrote:
> Hi Sebastian,
Hi,

> Thanks for your patchset. I think the perf support is great, but usually
> those new uAPI options should come with some selftests too.

You mean "tools/testing/selftests/futex/functional" ?
I could add something once it is merged. The API changed in this
submission vs the previous one where the "immutable" argument was added.
And I am waiting for some feedback on that.

The MPOL & NUMA bits could use also some documentation. Slowly once we
get there…

Sebastian