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: Remove support for IMMUTABLE

The FH_FLAG_IMMUTABLE flag was meant to avoid the reference counting on
the private hash and so to avoid the performance regression on big
machines.
With the switch to per-CPU counter this is no longer needed. That flag
was never useable on any released kernel.

Remove any support for IMMUTABLE while preserve the flags argument and
enforce it to be zero.

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

authored by

Sebastian Andrzej Siewior and committed by
Peter Zijlstra
760e6f7b fb3c553d

+3 -35
-2
include/uapi/linux/prctl.h
··· 367 367 /* FUTEX hash management */ 368 368 #define PR_FUTEX_HASH 78 369 369 # define PR_FUTEX_HASH_SET_SLOTS 1 370 - # define FH_FLAG_IMMUTABLE (1ULL << 0) 371 370 # define PR_FUTEX_HASH_GET_SLOTS 2 372 - # define PR_FUTEX_HASH_GET_IMMUTABLE 3 373 371 374 372 #endif /* _LINUX_PRCTL_H */
+3 -33
kernel/futex/core.c
··· 69 69 struct rcu_head rcu; 70 70 void *mm; 71 71 bool custom; 72 - bool immutable; 73 72 struct futex_hash_bucket queues[]; 74 73 }; 75 74 ··· 144 145 145 146 static bool futex_private_hash_get(struct futex_private_hash *fph) 146 147 { 147 - if (fph->immutable) 148 - return true; 149 148 return futex_ref_get(fph); 150 149 } 151 150 152 151 void futex_private_hash_put(struct futex_private_hash *fph) 153 152 { 154 - if (fph->immutable) 155 - return; 156 153 if (futex_ref_put(fph)) 157 154 wake_up_var(fph->mm); 158 155 } ··· 1525 1530 } 1526 1531 1527 1532 #define FH_CUSTOM 0x01 1528 - #define FH_IMMUTABLE 0x02 1529 1533 1530 1534 #ifdef CONFIG_FUTEX_PRIVATE_HASH 1531 1535 ··· 1794 1800 */ 1795 1801 scoped_guard(rcu) { 1796 1802 fph = rcu_dereference(mm->futex_phash); 1797 - if (fph && (!fph->hash_mask || fph->immutable)) { 1803 + if (fph && !fph->hash_mask) { 1798 1804 if (custom) 1799 1805 return -EBUSY; 1800 1806 return 0; ··· 1808 1814 1809 1815 fph->hash_mask = hash_slots ? hash_slots - 1 : 0; 1810 1816 fph->custom = custom; 1811 - fph->immutable = !!(flags & FH_IMMUTABLE); 1812 1817 fph->mm = mm; 1813 1818 1814 1819 for (i = 0; i < hash_slots; i++) ··· 1831 1838 mm->futex_phash_new = NULL; 1832 1839 1833 1840 if (fph) { 1834 - if (cur && (!cur->hash_mask || cur->immutable)) { 1841 + if (cur && !cur->hash_mask) { 1835 1842 /* 1836 1843 * If two threads simultaneously request the global 1837 1844 * hash then the first one performs the switch, ··· 1924 1931 return 0; 1925 1932 } 1926 1933 1927 - static int futex_hash_get_immutable(void) 1928 - { 1929 - struct futex_private_hash *fph; 1930 - 1931 - guard(rcu)(); 1932 - fph = rcu_dereference(current->mm->futex_phash); 1933 - if (fph && fph->immutable) 1934 - return 1; 1935 - if (fph && !fph->hash_mask) 1936 - return 1; 1937 - return 0; 1938 - } 1939 - 1940 1934 #else 1941 1935 1942 1936 static int futex_hash_allocate(unsigned int hash_slots, unsigned int flags) ··· 1936 1956 return 0; 1937 1957 } 1938 1958 1939 - static int futex_hash_get_immutable(void) 1940 - { 1941 - return 0; 1942 - } 1943 1959 #endif 1944 1960 1945 1961 int futex_hash_prctl(unsigned long arg2, unsigned long arg3, unsigned long arg4) ··· 1945 1969 1946 1970 switch (arg2) { 1947 1971 case PR_FUTEX_HASH_SET_SLOTS: 1948 - if (arg4 & ~FH_FLAG_IMMUTABLE) 1972 + if (arg4) 1949 1973 return -EINVAL; 1950 - if (arg4 & FH_FLAG_IMMUTABLE) 1951 - flags |= FH_IMMUTABLE; 1952 1974 ret = futex_hash_allocate(arg3, flags); 1953 1975 break; 1954 1976 1955 1977 case PR_FUTEX_HASH_GET_SLOTS: 1956 1978 ret = futex_hash_get_slots(); 1957 - break; 1958 - 1959 - case PR_FUTEX_HASH_GET_IMMUTABLE: 1960 - ret = futex_hash_get_immutable(); 1961 1979 break; 1962 1980 1963 1981 default: