mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-23 07:23:12 +02:00
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
This commit is contained in:
parent
80367ad01d
commit
7c4f75a21f
|
@ -80,6 +80,7 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
|
|||
int futex_hash_prctl(unsigned long arg2, unsigned long arg3, unsigned long arg4);
|
||||
|
||||
#ifdef CONFIG_FUTEX_PRIVATE_HASH
|
||||
int futex_hash_allocate_default(void);
|
||||
void futex_hash_free(struct mm_struct *mm);
|
||||
|
||||
static inline void futex_mm_init(struct mm_struct *mm)
|
||||
|
@ -88,6 +89,7 @@ static inline void futex_mm_init(struct mm_struct *mm)
|
|||
}
|
||||
|
||||
#else /* !CONFIG_FUTEX_PRIVATE_HASH */
|
||||
static inline int futex_hash_allocate_default(void) { return 0; }
|
||||
static inline void futex_hash_free(struct mm_struct *mm) { }
|
||||
static inline void futex_mm_init(struct mm_struct *mm) { }
|
||||
#endif /* CONFIG_FUTEX_PRIVATE_HASH */
|
||||
|
@ -107,6 +109,10 @@ static inline int futex_hash_prctl(unsigned long arg2, unsigned long arg3, unsig
|
|||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int futex_hash_allocate_default(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void futex_hash_free(struct mm_struct *mm) { }
|
||||
static inline void futex_mm_init(struct mm_struct *mm) { }
|
||||
|
||||
|
|
|
@ -2164,6 +2164,13 @@ static void rv_task_fork(struct task_struct *p)
|
|||
#define rv_task_fork(p) do {} while (0)
|
||||
#endif
|
||||
|
||||
static bool need_futex_hash_allocate_default(u64 clone_flags)
|
||||
{
|
||||
if ((clone_flags & (CLONE_THREAD | CLONE_VM)) != (CLONE_THREAD | CLONE_VM))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This creates a new process as a copy of the old one,
|
||||
* but does not actually start it yet.
|
||||
|
@ -2544,6 +2551,21 @@ __latent_entropy struct task_struct *copy_process(
|
|||
if (retval)
|
||||
goto bad_fork_cancel_cgroup;
|
||||
|
||||
/*
|
||||
* Allocate a default futex hash for the user process once the first
|
||||
* thread spawns.
|
||||
*/
|
||||
if (need_futex_hash_allocate_default(clone_flags)) {
|
||||
retval = futex_hash_allocate_default();
|
||||
if (retval)
|
||||
goto bad_fork_core_free;
|
||||
/*
|
||||
* If we fail beyond this point we don't free the allocated
|
||||
* futex hash map. We assume that another thread will be created
|
||||
* and makes use of it. The hash map will be freed once the main
|
||||
* thread terminates.
|
||||
*/
|
||||
}
|
||||
/*
|
||||
* From this point on we must avoid any synchronous user-space
|
||||
* communication until we take the tasklist-lock. In particular, we do
|
||||
|
|
|
@ -1294,6 +1294,17 @@ static int futex_hash_allocate(unsigned int hash_slots, bool custom)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int futex_hash_allocate_default(void)
|
||||
{
|
||||
if (!current->mm)
|
||||
return 0;
|
||||
|
||||
if (current->mm->futex_phash)
|
||||
return 0;
|
||||
|
||||
return futex_hash_allocate(16, false);
|
||||
}
|
||||
|
||||
static int futex_hash_get_slots(void)
|
||||
{
|
||||
struct futex_private_hash *fph;
|
||||
|
|
Loading…
Reference in New Issue
Block a user