Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

futex: Allow automatic allocation of process wide futex hash

Allocate a private futex hash with 16 slots if a task forks its first
thread.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20250416162921.513656-14-bigeasy@linutronix.de

authored by

Sebastian Andrzej Siewior and committed by
Peter Zijlstra
7c4f75a2 80367ad0

+39
+6
include/linux/futex.h
··· 80 80 int futex_hash_prctl(unsigned long arg2, unsigned long arg3, unsigned long arg4); 81 81 82 82 #ifdef CONFIG_FUTEX_PRIVATE_HASH 83 + int futex_hash_allocate_default(void); 83 84 void futex_hash_free(struct mm_struct *mm); 84 85 85 86 static inline void futex_mm_init(struct mm_struct *mm) ··· 89 88 } 90 89 91 90 #else /* !CONFIG_FUTEX_PRIVATE_HASH */ 91 + static inline int futex_hash_allocate_default(void) { return 0; } 92 92 static inline void futex_hash_free(struct mm_struct *mm) { } 93 93 static inline void futex_mm_init(struct mm_struct *mm) { } 94 94 #endif /* CONFIG_FUTEX_PRIVATE_HASH */ ··· 108 106 static inline int futex_hash_prctl(unsigned long arg2, unsigned long arg3, unsigned long arg4) 109 107 { 110 108 return -EINVAL; 109 + } 110 + static inline int futex_hash_allocate_default(void) 111 + { 112 + return 0; 111 113 } 112 114 static inline void futex_hash_free(struct mm_struct *mm) { } 113 115 static inline void futex_mm_init(struct mm_struct *mm) { }
+22
kernel/fork.c
··· 2164 2164 #define rv_task_fork(p) do {} while (0) 2165 2165 #endif 2166 2166 2167 + static bool need_futex_hash_allocate_default(u64 clone_flags) 2168 + { 2169 + if ((clone_flags & (CLONE_THREAD | CLONE_VM)) != (CLONE_THREAD | CLONE_VM)) 2170 + return false; 2171 + return true; 2172 + } 2173 + 2167 2174 /* 2168 2175 * This creates a new process as a copy of the old one, 2169 2176 * but does not actually start it yet. ··· 2551 2544 if (retval) 2552 2545 goto bad_fork_cancel_cgroup; 2553 2546 2547 + /* 2548 + * Allocate a default futex hash for the user process once the first 2549 + * thread spawns. 2550 + */ 2551 + if (need_futex_hash_allocate_default(clone_flags)) { 2552 + retval = futex_hash_allocate_default(); 2553 + if (retval) 2554 + goto bad_fork_core_free; 2555 + /* 2556 + * If we fail beyond this point we don't free the allocated 2557 + * futex hash map. We assume that another thread will be created 2558 + * and makes use of it. The hash map will be freed once the main 2559 + * thread terminates. 2560 + */ 2561 + } 2554 2562 /* 2555 2563 * From this point on we must avoid any synchronous user-space 2556 2564 * communication until we take the tasklist-lock. In particular, we do
+11
kernel/futex/core.c
··· 1294 1294 return 0; 1295 1295 } 1296 1296 1297 + int futex_hash_allocate_default(void) 1298 + { 1299 + if (!current->mm) 1300 + return 0; 1301 + 1302 + if (current->mm->futex_phash) 1303 + return 0; 1304 + 1305 + return futex_hash_allocate(16, false); 1306 + } 1307 + 1297 1308 static int futex_hash_get_slots(void) 1298 1309 { 1299 1310 struct futex_private_hash *fph;