Skip to content

Commit f38b1f2

Browse files
committed
Merge tag 'locking-futex-2025-07-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull futex updates from Thomas Gleixner: - Switch the reference counting to a RCU based per-CPU reference to address a performance bottleneck vs the single instance rcuref variant - Make the futex selftest build on 32-bit architectures which only support 64-bit time_t, e.g. RISCV-32 - Cleanups and improvements in selftests and futex bench * tag 'locking-futex-2025-07-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: selftests/futex: Fix spelling mistake "Succeffuly" -> "Successfully" selftests/futex: Define SYS_futex on 32-bit architectures with 64-bit time_t perf bench futex: Remove support for IMMUTABLE selftests/futex: Remove support for IMMUTABLE futex: Remove support for IMMUTABLE futex: Make futex_private_hash_get() static futex: Use RCU-based per-CPU reference counting instead of rcuref_t selftests/futex: Adapt the private hash test to RCU related changes
2 parents 02dc9d1 + e408922 commit f38b1f2

File tree

19 files changed

+326
-149
lines changed

19 files changed

+326
-149
lines changed

include/linux/futex.h

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,12 @@ int futex_hash_prctl(unsigned long arg2, unsigned long arg3, unsigned long arg4)
8585
#ifdef CONFIG_FUTEX_PRIVATE_HASH
8686
int futex_hash_allocate_default(void);
8787
void futex_hash_free(struct mm_struct *mm);
88-
89-
static inline void futex_mm_init(struct mm_struct *mm)
90-
{
91-
RCU_INIT_POINTER(mm->futex_phash, NULL);
92-
mm->futex_phash_new = NULL;
93-
mutex_init(&mm->futex_hash_lock);
94-
}
88+
int futex_mm_init(struct mm_struct *mm);
9589

9690
#else /* !CONFIG_FUTEX_PRIVATE_HASH */
9791
static inline int futex_hash_allocate_default(void) { return 0; }
98-
static inline void futex_hash_free(struct mm_struct *mm) { }
99-
static inline void futex_mm_init(struct mm_struct *mm) { }
92+
static inline int futex_hash_free(struct mm_struct *mm) { return 0; }
93+
static inline int futex_mm_init(struct mm_struct *mm) { return 0; }
10094
#endif /* CONFIG_FUTEX_PRIVATE_HASH */
10195

10296
#else /* !CONFIG_FUTEX */
@@ -118,8 +112,8 @@ static inline int futex_hash_allocate_default(void)
118112
{
119113
return 0;
120114
}
121-
static inline void futex_hash_free(struct mm_struct *mm) { }
122-
static inline void futex_mm_init(struct mm_struct *mm) { }
115+
static inline int futex_hash_free(struct mm_struct *mm) { return 0; }
116+
static inline int futex_mm_init(struct mm_struct *mm) { return 0; }
123117

124118
#endif
125119

include/linux/mm_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,11 @@ struct mm_struct {
10701070
struct mutex futex_hash_lock;
10711071
struct futex_private_hash __rcu *futex_phash;
10721072
struct futex_private_hash *futex_phash_new;
1073+
/* futex-ref */
1074+
unsigned long futex_batches;
1075+
struct rcu_head futex_rcu;
1076+
atomic_long_t futex_atomic;
1077+
unsigned int __percpu *futex_ref;
10731078
#endif
10741079

10751080
unsigned long hiwater_rss; /* High-watermark of RSS usage */

include/linux/sched/mm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static inline bool mmget_not_zero(struct mm_struct *mm)
140140

141141
/* mmput gets rid of the mappings and all user-space */
142142
extern void mmput(struct mm_struct *);
143-
#ifdef CONFIG_MMU
143+
#if defined(CONFIG_MMU) || defined(CONFIG_FUTEX_PRIVATE_HASH)
144144
/* same as above but performs the slow path from the async context. Can
145145
* be called from the atomic context as well
146146
*/

include/uapi/linux/prctl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,6 @@ struct prctl_mm_map {
367367
/* FUTEX hash management */
368368
#define PR_FUTEX_HASH 78
369369
# define PR_FUTEX_HASH_SET_SLOTS 1
370-
# define FH_FLAG_IMMUTABLE (1ULL << 0)
371370
# define PR_FUTEX_HASH_GET_SLOTS 2
372-
# define PR_FUTEX_HASH_GET_IMMUTABLE 3
373371

374372
#endif /* _LINUX_PRCTL_H */

init/Kconfig

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,13 +1716,9 @@ config FUTEX_PI
17161716
depends on FUTEX && RT_MUTEXES
17171717
default y
17181718

1719-
#
1720-
# marked broken for performance reasons; gives us one more cycle to sort things out.
1721-
#
17221719
config FUTEX_PRIVATE_HASH
17231720
bool
17241721
depends on FUTEX && !BASE_SMALL && MMU
1725-
depends on BROKEN
17261722
default y
17271723

17281724
config FUTEX_MPOL

kernel/fork.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,6 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
10461046
RCU_INIT_POINTER(mm->exe_file, NULL);
10471047
mmu_notifier_subscriptions_init(mm);
10481048
init_tlb_flush_pending(mm);
1049-
futex_mm_init(mm);
10501049
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !defined(CONFIG_SPLIT_PMD_PTLOCKS)
10511050
mm->pmd_huge_pte = NULL;
10521051
#endif
@@ -1061,6 +1060,9 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
10611060
mm->def_flags = 0;
10621061
}
10631062

1063+
if (futex_mm_init(mm))
1064+
goto fail_mm_init;
1065+
10641066
if (mm_alloc_pgd(mm))
10651067
goto fail_nopgd;
10661068

@@ -1090,6 +1092,8 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
10901092
fail_noid:
10911093
mm_free_pgd(mm);
10921094
fail_nopgd:
1095+
futex_hash_free(mm);
1096+
fail_mm_init:
10931097
free_mm(mm);
10941098
return NULL;
10951099
}
@@ -1145,7 +1149,7 @@ void mmput(struct mm_struct *mm)
11451149
}
11461150
EXPORT_SYMBOL_GPL(mmput);
11471151

1148-
#ifdef CONFIG_MMU
1152+
#if defined(CONFIG_MMU) || defined(CONFIG_FUTEX_PRIVATE_HASH)
11491153
static void mmput_async_fn(struct work_struct *work)
11501154
{
11511155
struct mm_struct *mm = container_of(work, struct mm_struct,

0 commit comments

Comments
 (0)