* [PATCH v6 1/8] x86/runtime-const: Introduce runtime_const_mask_32()
2026-07-28 5:25 [PATCH v6 0/8] futex: Use runtime constants for futex_hash computation K Prateek Nayak
@ 2026-07-28 5:25 ` K Prateek Nayak
2026-07-28 5:37 ` sashiko-bot
2026-07-28 5:25 ` [PATCH v6 2/8] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching K Prateek Nayak
` (6 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: K Prateek Nayak @ 2026-07-28 5:25 UTC (permalink / raw)
To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Sebastian Andrzej Siewior, Charlie Jenkins, Borislav Petkov,
Dave Hansen, x86
Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
linux-kernel, linux-s390, linux-riscv, linux-arm-kernel,
K Prateek Nayak, H. Peter Anvin, Sean Christopherson, Thomas Huth
From: Peter Zijlstra <peterz@infradead.org>
Futex hash computation requires a mask operation with read-only after
init data that will be converted to a runtime constant in the subsequent
commit.
Introduce runtime_const_mask_32 to further optimize the mask operation
in the futex hash computation hot path.
[ prateek: Broke off the x86 chunk, commit message. ]
Link: https://patch.msgid.link/20260227161841.GH606826@noisy.programming.kicks-ass.net
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v5..v6:
o Picked up Peter's S-o-b from his tree.
o No changes to the diff since v4.
---
arch/x86/include/asm/runtime-const.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/x86/include/asm/runtime-const.h b/arch/x86/include/asm/runtime-const.h
index 4cd94fdcb45e..b13f7036c1c9 100644
--- a/arch/x86/include/asm/runtime-const.h
+++ b/arch/x86/include/asm/runtime-const.h
@@ -41,6 +41,15 @@
:"+r" (__ret)); \
__ret; })
+#define runtime_const_mask_32(val, sym) ({ \
+ typeof(0u+(val)) __ret = (val); \
+ asm_inline("and $0x12345678, %k0\n1:\n" \
+ ".pushsection runtime_mask_" #sym ",\"a\"\n\t"\
+ ".long 1b - 4 - .\n" \
+ ".popsection" \
+ : "+r" (__ret)); \
+ __ret; })
+
#define runtime_const_init(type, sym) do { \
extern s32 __start_runtime_##type##_##sym[]; \
extern s32 __stop_runtime_##type##_##sym[]; \
@@ -65,6 +74,11 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val)
*(unsigned char *)where = val;
}
+static inline void __runtime_fixup_mask(void *where, unsigned long val)
+{
+ *(unsigned int *)where = val;
+}
+
static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
unsigned long val, s32 *start, s32 *end)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v6 1/8] x86/runtime-const: Introduce runtime_const_mask_32()
2026-07-28 5:25 ` [PATCH v6 1/8] x86/runtime-const: Introduce runtime_const_mask_32() K Prateek Nayak
@ 2026-07-28 5:37 ` sashiko-bot
2026-07-28 8:21 ` K Prateek Nayak
0 siblings, 1 reply; 18+ messages in thread
From: sashiko-bot @ 2026-07-28 5:37 UTC (permalink / raw)
To: K Prateek Nayak
Cc: Vasily Gorbik, Heiko Carstens, linux-s390, Alexander Gordeev
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The commit introduces `runtime_const_mask_32` for x86 but omits a generic fallback in `include/asm-generic/runtime-const.h`.
--
--- Patch [1]: [PATCH v6 1/8] x86/runtime-const: Introduce runtime_const_mask_32() ---
commit 664c491c817106934caf3b46117ff57570227576
Author: Peter Zijlstra <peterz@infradead.org>
x86/runtime-const: Introduce runtime_const_mask_32()
This commit introduces the runtime_const_mask_32() macro for the x86
architecture to optimize the mask operation in the futex hash computation
hot path. It also adds the __runtime_fixup_mask() helper to support
this functionality.
Link: https://patch.msgid.link/20260227161841.GH606826@noisy.programming.kicks-ass.net
> diff --git a/arch/x86/include/asm/runtime-const.h b/arch/x86/include/asm/runtime-const.h
> index 4cd94fdcb45e2..b13f7036c1c9b 100644
> --- a/arch/x86/include/asm/runtime-const.h
> +++ b/arch/x86/include/asm/runtime-const.h
[ ... ]
> @@ -41,6 +41,15 @@
> :"+r" (__ret)); \
> __ret; })
>
> +#define runtime_const_mask_32(val, sym) ({ \
> + typeof(0u+(val)) __ret = (val); \
> + asm_inline("and $0x12345678, %k0\n1:\n" \
> + ".pushsection runtime_mask_" #sym ",\"a\"\n\t"\
> + ".long 1b - 4 - .\n" \
> + ".popsection" \
> + : "+r" (__ret)); \
> + __ret; })
> +
[Severity: Medium]
Will this cause a build regression on non-x86 architectures when the generic
code starts using runtime_const_mask_32()?
The commit message mentions this will be used by the futex hash computation in
a subsequent commit. However, there doesn't appear to be a generic fallback
for this macro in include/asm-generic/runtime-const.h.
Without a generic fallback, it seems architectures that don't support or
haven't yet implemented runtime constants would fail to compile once the
generic futex code uses this macro.
Should a fallback like the following be introduced in
include/asm-generic/runtime-const.h alongside this x86 implementation to
maintain cross-architecture compatibility and strict bisectability?
#define runtime_const_mask_32(val, sym) ((val) & (sym))
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260728052540.4728-1-kprateek.nayak@amd.com?part=1
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v6 1/8] x86/runtime-const: Introduce runtime_const_mask_32()
2026-07-28 5:37 ` sashiko-bot
@ 2026-07-28 8:21 ` K Prateek Nayak
0 siblings, 0 replies; 18+ messages in thread
From: K Prateek Nayak @ 2026-07-28 8:21 UTC (permalink / raw)
To: sashiko-reviews
Cc: Vasily Gorbik, Heiko Carstens, linux-s390, Alexander Gordeev
Hello,
On 7/28/2026 11:07 AM, sashiko-bot@kernel.org wrote:
>> diff --git a/arch/x86/include/asm/runtime-const.h b/arch/x86/include/asm/runtime-const.h
>> index 4cd94fdcb45e2..b13f7036c1c9b 100644
>> --- a/arch/x86/include/asm/runtime-const.h
>> +++ b/arch/x86/include/asm/runtime-const.h
> [ ... ]
>> @@ -41,6 +41,15 @@
>> :"+r" (__ret)); \
>> __ret; })
>>
>> +#define runtime_const_mask_32(val, sym) ({ \
>> + typeof(0u+(val)) __ret = (val); \
>> + asm_inline("and $0x12345678, %k0\n1:\n" \
>> + ".pushsection runtime_mask_" #sym ",\"a\"\n\t"\
>> + ".long 1b - 4 - .\n" \
>> + ".popsection" \
>> + : "+r" (__ret)); \
>> + __ret; })
>> +
>
> [Severity: Medium]
> Will this cause a build regression on non-x86 architectures when the generic
> code starts using runtime_const_mask_32()?
That only happens at Patch 8 and by Patch 7, we have the generic
fallback. Everything is aligned before the first user is introduced.
>
> The commit message mentions this will be used by the futex hash computation in
> a subsequent commit. However, there doesn't appear to be a generic fallback
> for this macro in include/asm-generic/runtime-const.h.
>
> Without a generic fallback, it seems architectures that don't support or
> haven't yet implemented runtime constants would fail to compile once the
> generic futex code uses this macro.
>
> Should a fallback like the following be introduced in
> include/asm-generic/runtime-const.h alongside this x86 implementation to
> maintain cross-architecture compatibility and strict bisectability?
>
> #define runtime_const_mask_32(val, sym) ((val) & (sym))
Done in Patch 7. Bisectibility is preserved by having the plumbing
in place (in some order) before first user is introduced in Patch 8.
--
Thanks and Regards,
Prateek
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v6 2/8] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching
2026-07-28 5:25 [PATCH v6 0/8] futex: Use runtime constants for futex_hash computation K Prateek Nayak
2026-07-28 5:25 ` [PATCH v6 1/8] x86/runtime-const: Introduce runtime_const_mask_32() K Prateek Nayak
@ 2026-07-28 5:25 ` K Prateek Nayak
2026-07-28 5:35 ` sashiko-bot
2026-07-28 5:25 ` [PATCH v6 3/8] arm64/runtime-const: Introduce runtime_const_mask_32() K Prateek Nayak
` (5 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: K Prateek Nayak @ 2026-07-28 5:25 UTC (permalink / raw)
To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Sebastian Andrzej Siewior, Charlie Jenkins, Catalin Marinas,
Will Deacon
Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
linux-kernel, linux-s390, linux-riscv, linux-arm-kernel,
K Prateek Nayak, Jisheng Zhang
The current scheme to directly patch the kernel text for runtime
constants runs into the following issue with futex adapted to using
runtime constants on arm64:
Unable to handle kernel write to read-only memory at virtual address ...
The pc points to the *p assignment in the following call chain:
futex_init()
runtime_const_init(shift, __futex_shift)
__runtime_fixup_shift()
*p = cpu_to_le32(insn);
which suggests that core_initcall() is too late to patch the kernel text
directly unlike the "d_hash_shift" which is initialized during
vfs_caches_init_early() before the protections are in place.
Use aarch64_insn_patch_text_nosync() to patch the runtime constants
instead of doing it directly to allow runtime_const_init() slightly
later into the boot.
Since aarch64_insn_patch_text_nosync() calls caches_clean_inval_pou()
internally, __runtime_fixup_caches() ends up being redundant.
runtime_const_init() are rare and the overheads of multiple calls to
caches_clean_inval_pou() instead of batching them together should be
negligible in practice.
The cpu_to_le32() conversion of instruction isn't necessary since it is
handled later in the aarch64_insn_patch_text_nosync() call-chain:
aarch64_insn_patch_text_nosync(addr, insn)
aarch64_insn_write(addr, insn)
__aarch64_insn_write(addr, cpu_to_le32(insn))
Sashiko noted that aarch64_insn_patch_text_nosync() does not expect a
lm_alias() address and Catalin suggested it is safe to drop the
lm_alias() for runtime patching since the kernel text is readable. The
address passed to fixup function is interpreted as a __le32 and
dereferenced as is to read the opcode at the patch site.
No functional changes are intended.
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v5..v6:
o Picked up tags from Charlie. (Thanks a ton!)
o No changes to the diff.
---
arch/arm64/include/asm/runtime-const.h | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/include/asm/runtime-const.h b/arch/arm64/include/asm/runtime-const.h
index c3dbd3ae68f6..838145bc289d 100644
--- a/arch/arm64/include/asm/runtime-const.h
+++ b/arch/arm64/include/asm/runtime-const.h
@@ -7,6 +7,7 @@
#endif
#include <asm/cacheflush.h>
+#include <asm/text-patching.h>
/* Sigh. You can still run arm64 in BE mode */
#include <asm/byteorder.h>
@@ -50,34 +51,26 @@ static inline void __runtime_fixup_16(__le32 *p, unsigned int val)
u32 insn = le32_to_cpu(*p);
insn &= 0xffe0001f;
insn |= (val & 0xffff) << 5;
- *p = cpu_to_le32(insn);
-}
-
-static inline void __runtime_fixup_caches(void *where, unsigned int insns)
-{
- unsigned long va = (unsigned long)where;
- caches_clean_inval_pou(va, va + 4*insns);
+ aarch64_insn_patch_text_nosync(p, insn);
}
static inline void __runtime_fixup_ptr(void *where, unsigned long val)
{
- __le32 *p = lm_alias(where);
+ __le32 *p = where;
__runtime_fixup_16(p, val);
__runtime_fixup_16(p+1, val >> 16);
__runtime_fixup_16(p+2, val >> 32);
__runtime_fixup_16(p+3, val >> 48);
- __runtime_fixup_caches(where, 4);
}
/* Immediate value is 6 bits starting at bit #16 */
static inline void __runtime_fixup_shift(void *where, unsigned long val)
{
- __le32 *p = lm_alias(where);
+ __le32 *p = where;
u32 insn = le32_to_cpu(*p);
insn &= 0xffc0ffff;
insn |= (val & 63) << 16;
- *p = cpu_to_le32(insn);
- __runtime_fixup_caches(where, 1);
+ aarch64_insn_patch_text_nosync(p, insn);
}
static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v6 2/8] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching
2026-07-28 5:25 ` [PATCH v6 2/8] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching K Prateek Nayak
@ 2026-07-28 5:35 ` sashiko-bot
0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-07-28 5:35 UTC (permalink / raw)
To: K Prateek Nayak
Cc: linux-s390, Alexander Gordeev, Vasily Gorbik, Heiko Carstens
> The current scheme to directly patch the kernel text for runtime
> constants runs into the following issue with futex adapted to using
> runtime constants on arm64:
>
> Unable to handle kernel write to read-only memory at virtual address ...
>
> The pc points to the *p assignment in the following call chain:
>
> futex_init()
> runtime_const_init(shift, __futex_shift)
> __runtime_fixup_shift()
> *p = cpu_to_le32(insn);
>
> which suggests that core_initcall() is too late to patch the kernel text
> directly unlike the "d_hash_shift" which is initialized during
> [ ... ]
>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
> Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
> Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
> Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260728052540.4728-1-kprateek.nayak@amd.com?part=2
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v6 3/8] arm64/runtime-const: Introduce runtime_const_mask_32()
2026-07-28 5:25 [PATCH v6 0/8] futex: Use runtime constants for futex_hash computation K Prateek Nayak
2026-07-28 5:25 ` [PATCH v6 1/8] x86/runtime-const: Introduce runtime_const_mask_32() K Prateek Nayak
2026-07-28 5:25 ` [PATCH v6 2/8] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching K Prateek Nayak
@ 2026-07-28 5:25 ` K Prateek Nayak
2026-07-28 5:36 ` sashiko-bot
2026-07-28 5:25 ` [PATCH v6 4/8] riscv/runtime-const: Replace open-coded placeholder with RUNTIME_MAGIC K Prateek Nayak
` (4 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: K Prateek Nayak @ 2026-07-28 5:25 UTC (permalink / raw)
To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Sebastian Andrzej Siewior, Charlie Jenkins, Catalin Marinas,
Will Deacon
Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
linux-kernel, linux-s390, linux-riscv, linux-arm-kernel,
K Prateek Nayak, Jisheng Zhang, Samuel Holland
Futex hash computation requires a mask operation with read-only after
init data that will be converted to a runtime constant in the subsequent
commit.
Introduce runtime_const_mask_32 to further optimize the mask operation
in the futex hash computation hot path. Since all the current use-cases
are of the form GENMASK(n, 0), with n > 0, a single:
ubfx w0, w0, #0, #widthm1 // w0 = w0 [widthm1:0]
instruction is used for amd64 to improve instruction dinsity and
performance.
"Arm A-profile A64 Instruction Set Architecture" manual, Sec.
"A64 -- Base Instructions" [1] for UBFX instruction highlights the
immediate "width" is encoded as width minus 1 in imms (Bits [15:10])
which is patched by __runtime_fixup_mask() once the mask is known.
If a future use case arises that needs to tackle arbitrary mask,
consider using:
movz w1, #lo16, lsl #0
movk w1, #hi16, lsl #16
to patch the 32-bit mask in the asm block and return "__ret & (val)"
from runtime_const_mask_32() which allows compiler to further optimize
the logical and operation. __runtime_fixup_ptr() already patches a
"movz, + movk lsl #16" sequence which can be reused when the need
arises.
A possible implementation for this alternate scheme can be found at [2].
Assisted-by: Claude:claude-sonnet-4-6
Suggested-by: Samuel Holland <samuel.holland@sifive.com>
Suggested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Link: https://developer.arm.com/documentation/ddi0602/2026-03/Base-Instructions/ [1]
Link: https://lore.kernel.org/lkml/20260430094730.31624-4-kprateek.nayak@amd.com/ [2]
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v5..v6:
o Picked up tags from Charlie. (Thanks a ton!)
o Check the val before using __fls(). Flagged by Sashiko for potential
compiler optimizations that can consider val !=0 after an __fls() call
and then silently pass the BUG_ON().
---
arch/arm64/include/asm/runtime-const.h | 46 ++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/arch/arm64/include/asm/runtime-const.h b/arch/arm64/include/asm/runtime-const.h
index 838145bc289d..e221a868c48e 100644
--- a/arch/arm64/include/asm/runtime-const.h
+++ b/arch/arm64/include/asm/runtime-const.h
@@ -36,6 +36,17 @@
:"r" (0u+(val))); \
__ret; })
+#define runtime_const_mask_32(val, sym) ({ \
+ unsigned long __ret; \
+ asm_inline("1:\t" \
+ "ubfx %w0, %w1, #0, #32\n\t" \
+ ".pushsection runtime_mask_" #sym ",\"a\"\n\t" \
+ ".long 1b - .\n\t" \
+ ".popsection" \
+ :"=r" (__ret) \
+ :"r" (0u+(val))); \
+ __ret; })
+
#define runtime_const_init(type, sym) do { \
extern s32 __start_runtime_##type##_##sym[]; \
extern s32 __stop_runtime_##type##_##sym[]; \
@@ -73,6 +84,41 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val)
aarch64_insn_patch_text_nosync(p, insn);
}
+static inline void __runtime_fixup_mask(void *where, unsigned long val)
+{
+ unsigned int width = (val) ? __fls(val) + 1 : 0;
+ __le32 *p = where;
+ u32 insn;
+
+ /*
+ * XXX: Current implementation only supports patching masks of
+ * form GENMASK(n, 0) (n >= 0) using a single UBFX instruction
+ * to improve performance, density, and covers all the current
+ * use-cases.
+ *
+ * When the need arises to support any generic mask, and this
+ * BUG_ON() is tripped, consider using a:
+ *
+ * movz %w0, #imm16
+ * movk %w0, #imm16, lsl #16
+ *
+ * sequence to load the 32bit const mask, and perform a logical
+ * and outside the asm block before returning the result. Fixup
+ * can simply reuse the existing __runtime_fixup_16() to patch
+ * the individual mov instructions.
+ */
+ BUG_ON(!val || width > 32 || (GENMASK(width - 1, 0) != val));
+
+ /*
+ * The width of the mask is encoded as (width - 1) in imms
+ * which is 6 bits starting at bit #10.
+ */
+ insn = le32_to_cpu(*p);
+ insn &= 0xffff03ff;
+ insn |= ((width - 1) & 0x1f) << 10;
+ aarch64_insn_patch_text_nosync(p, insn);
+}
+
static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
unsigned long val, s32 *start, s32 *end)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v6 4/8] riscv/runtime-const: Replace open-coded placeholder with RUNTIME_MAGIC
2026-07-28 5:25 [PATCH v6 0/8] futex: Use runtime constants for futex_hash computation K Prateek Nayak
` (2 preceding siblings ...)
2026-07-28 5:25 ` [PATCH v6 3/8] arm64/runtime-const: Introduce runtime_const_mask_32() K Prateek Nayak
@ 2026-07-28 5:25 ` K Prateek Nayak
2026-07-28 5:34 ` sashiko-bot
2026-07-28 5:25 ` [PATCH v6 5/8] riscv/runtime-const: Introduce runtime_const_mask_32() K Prateek Nayak
` (3 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: K Prateek Nayak @ 2026-07-28 5:25 UTC (permalink / raw)
To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Sebastian Andrzej Siewior, Charlie Jenkins, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti
Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
linux-kernel, linux-s390, linux-riscv, linux-arm-kernel,
K Prateek Nayak, Jisheng Zhang, Guo Ren
Define the placeholder used for lui + addi[w] patching sequence as
RUNTIME_MAGIC and use that instead of open coding the constants in the
inline assembly.
No functional changes intended.
Suggested-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v5..v6:
o Picked up tags from Charlie. (Thanks a ton!)
---
arch/riscv/include/asm/runtime-const.h | 38 ++++++++++++++------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/arch/riscv/include/asm/runtime-const.h b/arch/riscv/include/asm/runtime-const.h
index 900db0a103d0..1ce02605d2e4 100644
--- a/arch/riscv/include/asm/runtime-const.h
+++ b/arch/riscv/include/asm/runtime-const.h
@@ -15,21 +15,23 @@
#include <linux/uaccess.h>
+#define RUNTIME_MAGIC __ASM_STR(0x89ABCDEF)
+
#ifdef CONFIG_32BIT
-#define runtime_const_ptr(sym) \
-({ \
- typeof(sym) __ret; \
- asm_inline(".option push\n\t" \
- ".option norvc\n\t" \
- "1:\t" \
- "lui %[__ret],0x89abd\n\t" \
- "addi %[__ret],%[__ret],-0x211\n\t" \
- ".option pop\n\t" \
- ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \
- ".long 1b - .\n\t" \
- ".popsection" \
- : [__ret] "=r" (__ret)); \
- __ret; \
+#define runtime_const_ptr(sym) \
+({ \
+ typeof(sym) __ret; \
+ asm_inline(".option push\n\t" \
+ ".option norvc\n\t" \
+ "1:\t" \
+ "lui %[__ret], %%hi(" RUNTIME_MAGIC ")\n\t" \
+ "addi %[__ret],%[__ret], %%lo(" RUNTIME_MAGIC ")\n\t" \
+ ".option pop\n\t" \
+ ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \
+ ".long 1b - .\n\t" \
+ ".popsection" \
+ : [__ret] "=r" (__ret)); \
+ __ret; \
})
#else
/*
@@ -46,10 +48,10 @@
".option push\n\t" \
".option norvc\n\t" \
"1:\t" \
- "lui %[__ret],0x89abd\n\t" \
- "lui %[__tmp],0x1234\n\t" \
- "addiw %[__ret],%[__ret],-0x211\n\t" \
- "addiw %[__tmp],%[__tmp],0x567\n\t" \
+ "lui %[__ret], %%hi(" RUNTIME_MAGIC ")\n\t" \
+ "lui %[__tmp], %%hi(" RUNTIME_MAGIC ")\n\t" \
+ "addiw %[__ret],%[__ret], %%lo(" RUNTIME_MAGIC ")\n\t" \
+ "addiw %[__tmp],%[__tmp], %%lo(" RUNTIME_MAGIC ")\n\t" \
#define RISCV_RUNTIME_CONST_64_BASE \
"slli %[__tmp],%[__tmp],32\n\t" \
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v6 5/8] riscv/runtime-const: Introduce runtime_const_mask_32()
2026-07-28 5:25 [PATCH v6 0/8] futex: Use runtime constants for futex_hash computation K Prateek Nayak
` (3 preceding siblings ...)
2026-07-28 5:25 ` [PATCH v6 4/8] riscv/runtime-const: Replace open-coded placeholder with RUNTIME_MAGIC K Prateek Nayak
@ 2026-07-28 5:25 ` K Prateek Nayak
2026-07-28 5:38 ` sashiko-bot
2026-07-28 5:25 ` [PATCH v6 6/8] s390/runtime-const: " K Prateek Nayak
` (2 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: K Prateek Nayak @ 2026-07-28 5:25 UTC (permalink / raw)
To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Sebastian Andrzej Siewior, Charlie Jenkins, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti
Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
linux-kernel, linux-s390, linux-riscv, linux-arm-kernel,
K Prateek Nayak, Ben Dooks, Thomas Huth, Samuel Holland,
Radim Krčmář, Jisheng Zhang, Guo Ren
Futex hash computation requires a mask operation with read-only after
init data that will be converted to a runtime constant in the subsequent
commit.
Introduce runtime_const_mask_32 to further optimize the mask operation
in the futex hash computation hot path. Since all the current use-cases
are of the form GENMASK(n, 0), with n > 0, following sequence:
srli a0, a1, imm
slli a0, a0, imm
is used for RISC-V where imm = (31 - width) to improve instruction
density and performance.
"The RISC-V Instruction Set Manual, Volume I - Unprivileged
Architecture" [1] Sec. 2.4.1 "Integer Register-Immediate Instructions"
notes the immediate shift for SRLI and SLLI are 5 bits wide starting at
bit #10. __runtime_fixup_shift() is reused to patch the immediate shifts
for the two instructions.
If a future use case arises that needs to tackle arbitrary mask,
consider using:
lui a0, 0x12346 # upper; +0x800 then >>12 for correct rounding
addi a0, a0, 0x678 # lower 12 bits
to patch the 32-bit mask in the asm block and return "__ret & (val)"
from runtime_const_mask_32() which allows compiler to further optimize
the logical and operation. __runtime_fixup_ptr() already patches a
lui + addi sequence which can be reused when the need arises.
A possible implementation for this alternate scheme can be found at [2].
Assisted-by: Claude:claude-sonnet-4-5
Suggested-by: Samuel Holland <samuel.holland@sifive.com>
Suggested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Link: https://docs.riscv.org/reference/isa/_attachments/riscv-unprivileged.pdf [1]
Link: https://lore.kernel.org/lkml/20260430094730.31624-6-kprateek.nayak@amd.com/ [2]
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Signed-off-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v5..v6:
o Picked up tags from charlie. (Thanks a ton!)
o Check the val before using __fls(). Flagged by Sashiko for potential
compiler optimizations that can consider val !=0 after an __fls() call
and then silently pass the BUG_ON().
---
arch/riscv/include/asm/asm.h | 1 +
arch/riscv/include/asm/runtime-const.h | 44 ++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index e9e8ba83e632..b8bf842d4c13 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -34,6 +34,7 @@
#define SZREG __REG_SEL(8, 4)
#define LGREG __REG_SEL(3, 2)
#define SRLI __REG_SEL(srliw, srli)
+#define SLLI __REG_SEL(slliw, slli)
#if __SIZEOF_POINTER__ == 8
#ifdef __ASSEMBLER__
diff --git a/arch/riscv/include/asm/runtime-const.h b/arch/riscv/include/asm/runtime-const.h
index 1ce02605d2e4..a472ebbf0971 100644
--- a/arch/riscv/include/asm/runtime-const.h
+++ b/arch/riscv/include/asm/runtime-const.h
@@ -159,6 +159,23 @@
__ret; \
})
+#define runtime_const_mask_32(val, sym) \
+({ \
+ u32 __ret; \
+ asm_inline(".option push\n\t" \
+ ".option norvc\n\t" \
+ "1:\t" \
+ SLLI " %[__ret],%[__val],12\n\t" \
+ SRLI " %[__ret],%[__ret],12\n\t" \
+ ".option pop\n\t" \
+ ".pushsection runtime_mask_" #sym ",\"a\"\n\t" \
+ ".long 1b - .\n\t" \
+ ".popsection" \
+ : [__ret] "=r" (__ret) \
+ : [__val] "r" (val)); \
+ __ret; \
+})
+
#define runtime_const_init(type, sym) do { \
extern s32 __start_runtime_##type##_##sym[]; \
extern s32 __stop_runtime_##type##_##sym[]; \
@@ -262,6 +279,33 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val)
mutex_unlock(&text_mutex);
}
+static inline void __runtime_fixup_mask(void *where, unsigned long val)
+{
+ unsigned int width = (val) ? __fls(val) + 1 : 0;
+
+ /*
+ * XXX: Current implementation only supports patching masks of
+ * form GENMASK(width, 0) (width >= 0) using a SRLI + SLLI
+ * sequence instead of LUI + ADDI + AND sequence to improve
+ * performance, density, and covers all the current use-cases.
+ *
+ * When the need arises to support any generic mask, and this
+ * BUG_ON() is tripped, consider using a:
+ *
+ * lui %[__ret], #imm16
+ * addi %[__ret], #imm16
+ *
+ * sequence to load the 32bit const mask, and perform a logical
+ * and outside the asm block before returning the result. Fixup
+ * can simply reuse the existing __runtime_fixup_32() to patch
+ * the LUI + ADDI sequence.
+ */
+ BUG_ON(!val || width > 31 || (GENMASK(width - 1, 0) != val));
+
+ __runtime_fixup_shift(where, 32 - width);
+ __runtime_fixup_shift(where + 4, 32 - width);
+}
+
static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
unsigned long val, s32 *start, s32 *end)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v6 5/8] riscv/runtime-const: Introduce runtime_const_mask_32()
2026-07-28 5:25 ` [PATCH v6 5/8] riscv/runtime-const: Introduce runtime_const_mask_32() K Prateek Nayak
@ 2026-07-28 5:38 ` sashiko-bot
0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-07-28 5:38 UTC (permalink / raw)
To: K Prateek Nayak
Cc: Vasily Gorbik, Heiko Carstens, linux-s390, Alexander Gordeev
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The BUG_ON bounds check in `__runtime_fixup_mask` incorrectly panics the kernel on a valid 32-bit all-ones mask (0xFFFFFFFF) due to an off-by-one error caused by confusing bit index with bit width.
- [Medium] The commit message and inline comments incorrectly describe the instruction sequence and immediate shift calculations, contradicting the correct code implementation.
--
--- Patch [5]: [PATCH v6 5/8] riscv/runtime-const: Introduce runtime_const_mask_32() ---
commit f8085a85ab8321e958c65177cacf4c654afce3c8
Author: K Prateek Nayak <kprateek.nayak@amd.com>
Subject: riscv/runtime-const: Introduce runtime_const_mask_32()
This commit introduces runtime_const_mask_32() to optimize mask operations in
the futex hash computation hot path on RISC-V. It implements this using left
and right shifts, patching the immediate values at runtime.
Link: https://docs.riscv.org/reference/isa/_attachments/riscv-unprivileged.pdf [1]
Link: https://lore.kernel.org/lkml/20260430094730.31624-6-kprateek.nayak@amd.com/ [2]
> Introduce runtime_const_mask_32 to further optimize the mask operation
> in the futex hash computation hot path. Since all the current use-cases
> are of the form GENMASK(n, 0), with n > 0, following sequence:
>
> srli a0, a1, imm
> slli a0, a0, imm
>
> is used for RISC-V where imm = (31 - width) to improve instruction
> density and performance.
[Severity: Medium]
Is this description in the commit message accurate?
The commit message describes using an srli + slli sequence and calculates the
shift as imm = 31 - width. However, the actual macro implementation correctly
uses an slli + srli sequence (shifting left then right) to clear the upper
bits, and __runtime_fixup_mask() uses imm = 32 - width.
Could the commit message be updated to match the implementation?
> diff --git a/arch/riscv/include/asm/runtime-const.h b/arch/riscv/include/asm/runtime-const.h
> index 1ce02605d2e43..a472ebbf09718 100644
> --- a/arch/riscv/include/asm/runtime-const.h
> +++ b/arch/riscv/include/asm/runtime-const.h
[ ... ]
> @@ -262,6 +279,33 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val)
> mutex_unlock(&text_mutex);
> }
>
> +static inline void __runtime_fixup_mask(void *where, unsigned long val)
> +{
> + unsigned int width = (val) ? __fls(val) + 1 : 0;
> +
> + /*
> + * XXX: Current implementation only supports patching masks of
> + * form GENMASK(width, 0) (width >= 0) using a SRLI + SLLI
[Severity: Medium]
Is the inline documentation here slightly out of sync with the code?
Similar to the commit message, this mentions SRLI + SLLI and GENMASK(width, 0),
but the code below uses GENMASK(width - 1, 0) and the macro actually implements
SLLI + SRLI.
> + * sequence instead of LUI + ADDI + AND sequence to improve
[ ... ]
> + * and outside the asm block before returning the result. Fixup
> + * can simply reuse the existing __runtime_fixup_32() to patch
> + * the LUI + ADDI sequence.
> + */
> + BUG_ON(!val || width > 31 || (GENMASK(width - 1, 0) != val));
[Severity: Medium]
Does this BUG_ON() condition reject a valid 32-bit mask?
When the mask is all ones (0xFFFFFFFF), __fls(val) + 1 evaluates to a width
of 32. The width > 31 check would trip the BUG_ON() and panic the kernel.
A shift of 32 - 32 = 0 is mathematically valid for RISC-V, as using slliw
and srliw with a 0 shift correctly truncates and zero-extends the 32-bit
value to 64 bits.
Should this check allow a full 32-bit mask instead?
> +
> + __runtime_fixup_shift(where, 32 - width);
> + __runtime_fixup_shift(where + 4, 32 - width);
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260728052540.4728-1-kprateek.nayak@amd.com?part=5
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v6 6/8] s390/runtime-const: Introduce runtime_const_mask_32()
2026-07-28 5:25 [PATCH v6 0/8] futex: Use runtime constants for futex_hash computation K Prateek Nayak
` (4 preceding siblings ...)
2026-07-28 5:25 ` [PATCH v6 5/8] riscv/runtime-const: Introduce runtime_const_mask_32() K Prateek Nayak
@ 2026-07-28 5:25 ` K Prateek Nayak
2026-07-28 5:36 ` sashiko-bot
2026-07-28 5:25 ` [PATCH v6 7/8] asm-generic/runtime-const: Add dummy runtime_const_mask_32() K Prateek Nayak
2026-07-28 5:25 ` [PATCH v6 8/8] futex: Use runtime constants for __futex_hash() hot path K Prateek Nayak
7 siblings, 1 reply; 18+ messages in thread
From: K Prateek Nayak @ 2026-07-28 5:25 UTC (permalink / raw)
To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Sebastian Andrzej Siewior, Charlie Jenkins, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev
Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
linux-kernel, linux-s390, linux-riscv, linux-arm-kernel,
K Prateek Nayak, Christian Borntraeger, Sven Schnelle
Futex hash computation requires a mask operation with read-only after
init data that will be converted to a runtime constant in the subsequent
commit.
Introduce runtime_const_mask_32 to further optimize the mask operation
in the futex hash computation hot path.
GCC generates a:
nilf %r1,<imm32>
to tackle arbitrary 32-bit masks and the same is implemented here.
Immediate patching pattern for __runtime_fixup_mask() has been adopted
from __runtime_fixup_ptr().
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v5..v6:
o No changes.
---
arch/s390/include/asm/runtime-const.h | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/s390/include/asm/runtime-const.h b/arch/s390/include/asm/runtime-const.h
index 17878b1d048c..7b71156031ec 100644
--- a/arch/s390/include/asm/runtime-const.h
+++ b/arch/s390/include/asm/runtime-const.h
@@ -33,6 +33,20 @@
__ret; \
})
+#define runtime_const_mask_32(val, sym) \
+({ \
+ unsigned int __ret = (val); \
+ \
+ asm_inline( \
+ "0: nilf %[__ret],12\n" \
+ ".pushsection runtime_mask_" #sym ",\"a\"\n" \
+ ".long 0b - .\n" \
+ ".popsection" \
+ : [__ret] "+d" (__ret) \
+ : : "cc"); \
+ __ret; \
+})
+
#define runtime_const_init(type, sym) do { \
extern s32 __start_runtime_##type##_##sym[]; \
extern s32 __stop_runtime_##type##_##sym[]; \
@@ -43,12 +57,12 @@
__stop_runtime_##type##_##sym); \
} while (0)
-/* 32-bit immediate for iihf and iilf in bits in I2 field */
static inline void __runtime_fixup_32(u32 *p, unsigned int val)
{
s390_kernel_write(p, &val, sizeof(val));
}
+/* 32-bit immediate for iihf and iilf in bits in I2 field */
static inline void __runtime_fixup_ptr(void *where, unsigned long val)
{
__runtime_fixup_32(where + 2, val >> 32);
@@ -65,6 +79,12 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val)
s390_kernel_write(where, &insn, sizeof(insn));
}
+/* 32-bit immediate for nilf in bits in I2 field */
+static inline void __runtime_fixup_mask(void *where, unsigned long val)
+{
+ __runtime_fixup_32(where + 2, val);
+}
+
static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
unsigned long val, s32 *start, s32 *end)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v6 6/8] s390/runtime-const: Introduce runtime_const_mask_32()
2026-07-28 5:25 ` [PATCH v6 6/8] s390/runtime-const: " K Prateek Nayak
@ 2026-07-28 5:36 ` sashiko-bot
0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-07-28 5:36 UTC (permalink / raw)
To: K Prateek Nayak
Cc: Alexander Gordeev, linux-s390, Vasily Gorbik, Heiko Carstens
> Futex hash computation requires a mask operation with read-only after
> init data that will be converted to a runtime constant in the subsequent
> commit.
>
> Introduce runtime_const_mask_32 to further optimize the mask operation
> in the futex hash computation hot path.
>
> GCC generates a:
>
> nilf %r1,<imm32>
>
> to tackle arbitrary 32-bit masks and the same is implemented here.
> Immediate patching pattern for __runtime_fixup_mask() has been adopted
> from __runtime_fixup_ptr().
>
> Acked-by: Heiko Carstens <hca@linux.ibm.com>
> Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260728052540.4728-1-kprateek.nayak@amd.com?part=6
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v6 7/8] asm-generic/runtime-const: Add dummy runtime_const_mask_32()
2026-07-28 5:25 [PATCH v6 0/8] futex: Use runtime constants for futex_hash computation K Prateek Nayak
` (5 preceding siblings ...)
2026-07-28 5:25 ` [PATCH v6 6/8] s390/runtime-const: " K Prateek Nayak
@ 2026-07-28 5:25 ` K Prateek Nayak
2026-07-28 5:34 ` sashiko-bot
2026-07-28 5:25 ` [PATCH v6 8/8] futex: Use runtime constants for __futex_hash() hot path K Prateek Nayak
7 siblings, 1 reply; 18+ messages in thread
From: K Prateek Nayak @ 2026-07-28 5:25 UTC (permalink / raw)
To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Sebastian Andrzej Siewior, Charlie Jenkins
Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
linux-kernel, linux-s390, linux-riscv, linux-arm-kernel,
K Prateek Nayak
From: Peter Zijlstra <peterz@infradead.org>
Add a dummy runtime_const_mask_32() for all the architectures that do
not support runtime-const.
Link: https://patch.msgid.link/20260227161841.GH606826@noisy.programming.kicks-ass.net
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v5..v6:
o Picked up tags from Charlie. (Thanks a ton!)
o Picked up Peter's S-o-b from his tree.
---
include/asm-generic/runtime-const.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/asm-generic/runtime-const.h b/include/asm-generic/runtime-const.h
index 670499459514..03e6e3e02401 100644
--- a/include/asm-generic/runtime-const.h
+++ b/include/asm-generic/runtime-const.h
@@ -10,6 +10,7 @@
*/
#define runtime_const_ptr(sym) (sym)
#define runtime_const_shift_right_32(val, sym) ((u32)(val)>>(sym))
+#define runtime_const_mask_32(val, sym) ((u32)(val)&(sym))
#define runtime_const_init(type,sym) do { } while (0)
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v6 8/8] futex: Use runtime constants for __futex_hash() hot path
2026-07-28 5:25 [PATCH v6 0/8] futex: Use runtime constants for futex_hash computation K Prateek Nayak
` (6 preceding siblings ...)
2026-07-28 5:25 ` [PATCH v6 7/8] asm-generic/runtime-const: Add dummy runtime_const_mask_32() K Prateek Nayak
@ 2026-07-28 5:25 ` K Prateek Nayak
2026-07-28 5:42 ` sashiko-bot
7 siblings, 1 reply; 18+ messages in thread
From: K Prateek Nayak @ 2026-07-28 5:25 UTC (permalink / raw)
To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
Sebastian Andrzej Siewior, Charlie Jenkins, Borislav Petkov,
Dave Hansen, x86, Catalin Marinas, Will Deacon, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev
Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
linux-kernel, linux-s390, linux-riscv, linux-arm-kernel,
K Prateek Nayak, H. Peter Anvin, Sean Christopherson, Thomas Huth,
Jisheng Zhang, Ben Dooks, Samuel Holland,
Radim Krčmář, Guo Ren, Christian Borntraeger,
Sven Schnelle
From: Peter Zijlstra <peterz@infradead.org>
Runtime constify the read-only after init data __futex_shift(shift_32),
__futex_mask(mask_32), and __futex_queues(ptr) used in __futex_hash()
hot path to avoid referencing global variable.
This also allows __futex_queues to be allocated dynamically to
"nr_node_ids" slots instead of reserving config dependent MAX_NUMNODES
(1 << CONFIG_NODES_SHIFT) worth of slots upfront.
Runtime constants are initialized before their first access and
runtime_const_init() provides necessary barrier to ensure subsequent
accesses are not reordered against their initialization.
No functional changes intended.
[ prateek: Dynamically allocate __futex_queues, mark the global data
__ro_after_init since they are constified after futex_init(). ]
Link: https://patch.msgid.link/20260227161841.GH606826@noisy.programming.kicks-ass.net
Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> # MAX_NUMNODES bloat
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v5..v6:
o Picked up tags from Charlie. (Thanks a ton!)
o Picked up Peter's S-o-b from his tree.
o Added a barrier after runtime_const_init() after to prevent compilers
from re-ordering a later runtime const usage in the init function with
their initialization. (Sashiko; Reported by Intel test robot with a
GCC14 build).
(https://lore.kernel.org/lkml/alNgNvhIkBfkGo1Y@xsang-OptiPlex-9020/)
---
include/asm-generic/vmlinux.lds.h | 5 +++-
kernel/futex/core.c | 44 ++++++++++++++++++-------------
2 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 5659f4b5a125..53207901d4c1 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -970,7 +970,10 @@
RUNTIME_CONST(ptr, __dentry_cache) \
RUNTIME_CONST(ptr, __names_cache) \
RUNTIME_CONST(ptr, __filp_cache) \
- RUNTIME_CONST(ptr, __bfilp_cache)
+ RUNTIME_CONST(ptr, __bfilp_cache) \
+ RUNTIME_CONST(shift, __futex_shift) \
+ RUNTIME_CONST(mask, __futex_mask) \
+ RUNTIME_CONST(ptr, __futex_queues)
/* Alignment must be consistent with (kunit_suite *) in include/kunit/test.h */
#define KUNIT_TABLE() \
diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index 233b926f5624..1eb83c9118a4 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -48,23 +48,19 @@
#include <vdso/futex.h>
+#include <asm/runtime-const.h>
+
#include "futex.h"
#include "../locking/rtmutex_common.h"
-/*
- * The base of the bucket array and its size are always used together
- * (after initialization only in futex_hash()), so ensure that they
- * reside in the same cacheline.
- */
-static struct {
- unsigned long hashmask;
- unsigned int hashshift;
- struct futex_hash_bucket *queues[MAX_NUMNODES];
-} __futex_data __read_mostly __aligned(2*sizeof(long));
+static u32 __futex_mask __ro_after_init;
+static u32 __futex_shift __ro_after_init;
+static struct futex_hash_bucket **__futex_queues __ro_after_init;
-#define futex_hashmask (__futex_data.hashmask)
-#define futex_hashshift (__futex_data.hashshift)
-#define futex_queues (__futex_data.queues)
+static __always_inline struct futex_hash_bucket **futex_queues(void)
+{
+ return runtime_const_ptr(__futex_queues);
+}
struct futex_private_hash {
int state;
@@ -395,13 +391,13 @@ __futex_hash(union futex_key *key, struct futex_private_hash *fph, struct futex_
* NOTE: this isn't perfectly uniform, but it is fast and
* handles sparse node masks.
*/
- node = (hash >> futex_hashshift) % nr_node_ids;
+ node = runtime_const_shift_right_32(hash, __futex_shift) % nr_node_ids;
if (!node_possible(node)) {
node = find_next_bit_wrap(node_possible_map.bits, nr_node_ids, node);
}
}
- return &futex_queues[node][hash & futex_hashmask];
+ return &futex_queues()[node][runtime_const_mask_32(hash, __futex_mask)];
}
/**
@@ -1921,7 +1917,7 @@ int futex_hash_allocate_default(void)
* 16 <= threads * 4 <= global hash size
*/
buckets = roundup_pow_of_two(4 * threads);
- buckets = clamp(buckets, 16, futex_hashmask + 1);
+ buckets = clamp(buckets, 16, __futex_mask + 1);
if (current_buckets >= buckets)
return 0;
@@ -2019,10 +2015,21 @@ static int __init futex_init(void)
hashsize = max(4, hashsize);
hashsize = roundup_pow_of_two(hashsize);
#endif
- futex_hashshift = ilog2(hashsize);
+ __futex_mask = hashsize - 1;
+ __futex_shift = ilog2(hashsize);
size = sizeof(struct futex_hash_bucket) * hashsize;
order = get_order(size);
+ __futex_queues = kcalloc(nr_node_ids, sizeof(*__futex_queues), GFP_KERNEL);
+
+ runtime_const_init(shift, __futex_shift);
+ runtime_const_init(mask, __futex_mask);
+ runtime_const_init(ptr, __futex_queues);
+
+ barrier();
+
+ BUG_ON(!futex_queues());
+
for_each_node(n) {
struct futex_hash_bucket *table;
@@ -2036,10 +2043,9 @@ static int __init futex_init(void)
for (i = 0; i < hashsize; i++)
futex_hash_bucket_init(&table[i]);
- futex_queues[n] = table;
+ futex_queues()[n] = table;
}
- futex_hashmask = hashsize - 1;
pr_info("futex hash table entries: %lu (%lu bytes on %d NUMA nodes, total %lu KiB, %s).\n",
hashsize, size, num_possible_nodes(), size * num_possible_nodes() / 1024,
order > MAX_PAGE_ORDER ? "vmalloc" : "linear");
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v6 8/8] futex: Use runtime constants for __futex_hash() hot path
2026-07-28 5:25 ` [PATCH v6 8/8] futex: Use runtime constants for __futex_hash() hot path K Prateek Nayak
@ 2026-07-28 5:42 ` sashiko-bot
0 siblings, 0 replies; 18+ messages in thread
From: sashiko-bot @ 2026-07-28 5:42 UTC (permalink / raw)
To: K Prateek Nayak
Cc: linux-s390, Alexander Gordeev, Vasily Gorbik, Heiko Carstens
> From: Peter Zijlstra <peterz@infradead.org>
>
> Runtime constify the read-only after init data __futex_shift(shift_32),
> __futex_mask(mask_32), and __futex_queues(ptr) used in __futex_hash()
> hot path to avoid referencing global variable.
>
> This also allows __futex_queues to be allocated dynamically to
> "nr_node_ids" slots instead of reserving config dependent MAX_NUMNODES
> (1 << CONFIG_NODES_SHIFT) worth of slots upfront.
>
> Runtime constants are initialized before their first access and
> runtime_const_init() provides necessary barrier to ensure subsequent
> accesses are not reordered against their initialization.
>
> No functional changes intended.
>
> [ prateek: Dynamically allocate __futex_queues, mark the global data
> __ro_after_init since they are constified after futex_init(). ]
>
> Link: https://patch.msgid.link/20260227161841.GH606826@noisy.programming.kicks-ass.net
> Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> # MAX_NUMNODES bloat
> Signed-off-by: Peter Zijlstra <peterz@infradead.org>
> Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
> Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
> Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260728052540.4728-1-kprateek.nayak@amd.com?part=8
^ permalink raw reply [flat|nested] 18+ messages in thread