* [PATCH] slab: align ZERO_SIZE_PTR to ARCH_KMALLOC_MINALIGN
@ 2026-08-08 10:56 Karl Mehltretter
2026-08-10 14:26 ` Catalin Marinas
0 siblings, 1 reply; 3+ messages in thread
From: Karl Mehltretter @ 2026-08-08 10:56 UTC (permalink / raw)
To: Vlastimil Babka, Harry Yoo, Andrew Morton
Cc: Karl Mehltretter, Rasmus Villemoes, Hao Li, Christoph Lameter,
David Rientjes, Roman Gushchin, Catalin Marinas, linux-mm,
linux-kernel, llvm
The kmalloc entry points are annotated with __assume_kmalloc_alignment
but return ZERO_SIZE_PTR, currently (void *)16, for zero-size requests.
This violates the annotation when ARCH_KMALLOC_MINALIGN exceeds 16.
This can mislead compiler optimizations. Current compilers retain the
ZERO_OR_NULL_PTR() range check, but GCC and Clang eliminate an exact
ZERO_SIZE_PTR comparison after an annotated allocation. Clang's UBSAN
also reports the failed alignment assumption on armv5.
Set ZERO_SIZE_PTR to ARCH_KMALLOC_MINALIGN when it exceeds 16 and keep
the existing value otherwise. Assert that the alignment does not exceed
128, which keeps the sentinel below PAGE_SIZE and the low pointer
poison values. Deriving the value from the architecture also avoids
changing architectures such as s390, where low absolute addresses are
valid.
Fixes: 94a58c360a45 ("slab.h: sprinkle __assume_aligned attributes")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
Notes:
This version is based on the RFC discussion [1].
[1] https://lore.kernel.org/r/20260712120728.96628-1-kmehltretter@gmail.com
A tree-wide audit found no users depending on the numeric value of
ZERO_SIZE_PTR.
The static assertion follows the ARCH_KMALLOC_MINALIGN fallback, the
first point where the macro is guaranteed to be defined.
Tested on bcc44b6785f21:
- armv5, armv7, mips64, ppc44x and sh4 with minimum alignments from
32 to 128
- x86_64, arm64, riscv64, s390x and m68k as unchanged controls
- Clang 21 with CONFIG_UBSAN_ALIGNMENT on armv5 no longer shows the
alignment assumption report
- no text, data or bss size change on armv5 or arm64
- the exact ZERO_SIZE_PTR comparison remains in armv5 code
generation
The sh4 test needed two unrelated workarounds, both reproduced on the
unpatched tree: compiling tcp_output.c at -O1 because of a GCC 15.2
hang, and disabling USB_OHCI_HCD because of an sm501-usb boot failure.
include/linux/slab.h | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 32c9f8ed7ae20..0798a714da87f 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -259,13 +259,16 @@ enum _slab_flag_bits {
/*
* ZERO_SIZE_PTR will be returned for zero sized kmalloc requests.
+ * It satisfies the alignment promised by __assume_kmalloc_alignment
+ * and keeps the historic value 16 where that is already aligned.
*
* Dereferencing ZERO_SIZE_PTR will lead to a distinct access fault.
*
* ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
* Both make kfree a no-op.
*/
-#define ZERO_SIZE_PTR ((void *)16)
+#define ZERO_SIZE_PTR ((void *)(ARCH_KMALLOC_MINALIGN > 16 ? \
+ ARCH_KMALLOC_MINALIGN : 16))
#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
(unsigned long)ZERO_SIZE_PTR)
@@ -622,6 +625,12 @@ static inline bool kmem_dump_obj(void *object) { return false; }
#define KMALLOC_SHIFT_LOW ilog2(KMALLOC_MIN_SIZE)
#endif
+/*
+ * Keep ZERO_SIZE_PTR below PAGE_SIZE and the low pointer poison values.
+ * 128 is the largest in-tree ARCH_KMALLOC_MINALIGN.
+ */
+static_assert(ARCH_KMALLOC_MINALIGN <= 128);
+
/*
* Setting ARCH_SLAB_MINALIGN in arch headers allows a different alignment.
* Intended for arches that get misalignment faults even for 64 bit integer
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] slab: align ZERO_SIZE_PTR to ARCH_KMALLOC_MINALIGN
2026-08-08 10:56 [PATCH] slab: align ZERO_SIZE_PTR to ARCH_KMALLOC_MINALIGN Karl Mehltretter
@ 2026-08-10 14:26 ` Catalin Marinas
2026-08-11 5:43 ` Karl Mehltretter
0 siblings, 1 reply; 3+ messages in thread
From: Catalin Marinas @ 2026-08-10 14:26 UTC (permalink / raw)
To: Karl Mehltretter
Cc: Vlastimil Babka, Harry Yoo, Andrew Morton, Rasmus Villemoes,
Hao Li, Christoph Lameter, David Rientjes, Roman Gushchin,
linux-mm, linux-kernel, llvm
On Sat, Aug 08, 2026 at 12:56:22PM +0200, Karl Mehltretter wrote:
> diff --git a/include/linux/slab.h b/include/linux/slab.h
> index 32c9f8ed7ae20..0798a714da87f 100644
> --- a/include/linux/slab.h
> +++ b/include/linux/slab.h
> @@ -259,13 +259,16 @@ enum _slab_flag_bits {
>
> /*
> * ZERO_SIZE_PTR will be returned for zero sized kmalloc requests.
> + * It satisfies the alignment promised by __assume_kmalloc_alignment
> + * and keeps the historic value 16 where that is already aligned.
> *
> * Dereferencing ZERO_SIZE_PTR will lead to a distinct access fault.
> *
> * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
> * Both make kfree a no-op.
> */
> -#define ZERO_SIZE_PTR ((void *)16)
> +#define ZERO_SIZE_PTR ((void *)(ARCH_KMALLOC_MINALIGN > 16 ? \
> + ARCH_KMALLOC_MINALIGN : 16))
>
> #define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
> (unsigned long)ZERO_SIZE_PTR)
> @@ -622,6 +625,12 @@ static inline bool kmem_dump_obj(void *object) { return false; }
> #define KMALLOC_SHIFT_LOW ilog2(KMALLOC_MIN_SIZE)
> #endif
>
> +/*
> + * Keep ZERO_SIZE_PTR below PAGE_SIZE and the low pointer poison values.
> + * 128 is the largest in-tree ARCH_KMALLOC_MINALIGN.
> + */
> +static_assert(ARCH_KMALLOC_MINALIGN <= 128);
I'm not sure we should bother with this, or at least make it strictly
less than PAGE_SIZE since 128 doesn't have any meaning for the slab
allocator.
Otherwise,
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] slab: align ZERO_SIZE_PTR to ARCH_KMALLOC_MINALIGN
2026-08-10 14:26 ` Catalin Marinas
@ 2026-08-11 5:43 ` Karl Mehltretter
0 siblings, 0 replies; 3+ messages in thread
From: Karl Mehltretter @ 2026-08-11 5:43 UTC (permalink / raw)
To: Catalin Marinas
Cc: Vlastimil Babka, Harry Yoo, Andrew Morton, Rasmus Villemoes,
Hao Li, Christoph Lameter, David Rientjes, Roman Gushchin,
linux-mm, linux-kernel, llvm
On Mon, Aug 10, 2026 at 03:26:37PM +0100, Catalin Marinas wrote:
> On Sat, Aug 08, 2026 at 12:56:22PM +0200, Karl Mehltretter wrote:
> > diff --git a/include/linux/slab.h b/include/linux/slab.h
> > index 32c9f8ed7ae20..0798a714da87f 100644
> > --- a/include/linux/slab.h
> > +++ b/include/linux/slab.h
> > @@ -259,13 +259,16 @@ enum _slab_flag_bits {
> >
> > /*
> > * ZERO_SIZE_PTR will be returned for zero sized kmalloc requests.
> > + * It satisfies the alignment promised by __assume_kmalloc_alignment
> > + * and keeps the historic value 16 where that is already aligned.
> > *
> > * Dereferencing ZERO_SIZE_PTR will lead to a distinct access fault.
> > *
> > * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
> > * Both make kfree a no-op.
> > */
> > -#define ZERO_SIZE_PTR ((void *)16)
> > +#define ZERO_SIZE_PTR ((void *)(ARCH_KMALLOC_MINALIGN > 16 ? \
> > + ARCH_KMALLOC_MINALIGN : 16))
> >
> > #define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
> > (unsigned long)ZERO_SIZE_PTR)
> > @@ -622,6 +625,12 @@ static inline bool kmem_dump_obj(void *object) { return false; }
> > #define KMALLOC_SHIFT_LOW ilog2(KMALLOC_MIN_SIZE)
> > #endif
> >
> > +/*
> > + * Keep ZERO_SIZE_PTR below PAGE_SIZE and the low pointer poison values.
> > + * 128 is the largest in-tree ARCH_KMALLOC_MINALIGN.
> > + */
> > +static_assert(ARCH_KMALLOC_MINALIGN <= 128);
>
> I'm not sure we should bother with this, or at least make it strictly
> less than PAGE_SIZE since 128 doesn't have any meaning for the slab
> allocator.
>
Thanks for the review!
The case I had in mind when choosing 128 was POISON_POINTER_DELTA == 0,
where LIST_POISON1 is 256 (0x100). With the current range check, an
architecture with non-coherent DMA and 256-byte cache lines would make
kfree(LIST_POISON1) a silent no-op.
Looking at this again, I think ZERO_OR_NULL_PTR() should match only NULL
and ZERO_SIZE_PTR, rather than the whole range below the sentinel. This
would also stop unrelated low pointer values from being silently
accepted. I'll include that change in v2.
Thanks,
Karl
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-11 5:43 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-08 10:56 [PATCH] slab: align ZERO_SIZE_PTR to ARCH_KMALLOC_MINALIGN Karl Mehltretter
2026-08-10 14:26 ` Catalin Marinas
2026-08-11 5:43 ` Karl Mehltretter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox