Re: [PATCH] mm/slub: initialize allocated object's freepointer before debug check
From: Harry Yoo (Oracle)
Date: Thu Apr 30 2026 - 04:48:04 EST
On Thu, Apr 30, 2026 at 04:35:04PM +0800, hu.shengming@xxxxxxxxxx wrote:
> From: Shengming Hu <hu.shengming@xxxxxxxxxx>
>
> The deferred-freelist path allocates the first object from a fresh slab
> before building the freelist for the remaining objects. Unlike the old
> path, the selected object is no longer the head of a pre-built freelist,
> so its freepointer remains uninitialized.
>
> alloc_debug_processing() still checks its freepointer. As a result,
> boot can report:
>
> BUG kmem_cache (Tainted: G B W T ): Freepointer corrupt
>
> Restore the old invariant by storing a valid freepointer in the selected
> object before alloc_debug_processing() runs. The pointer is the head of
> the leftover freelist, matching what the old pre-built freelist path
> would have left in the allocated object.
>
> Fixes: 895272864130 ("mm/slub: defer freelist construction until after bulk allocation from a new slab")
> Reported-by: kernel test robot <oliver.sang@xxxxxxxxx>
> Closes: https://lore.kernel.org/oe-lkp/202604301428.e2b8d3dd-lkp@xxxxxxxxx
> Signed-off-by: Shengming Hu <hu.shengming@xxxxxxxxxx>
> ---
When the patch did not land the mainline yet (torvalds/linux), we don't
create a separate fix patch because commiting a broken patch and then
adding a fix for that creates unnecessary history. We can avoid that
as it did not land yet.
Could you please send a v8 of the original patch?
In that case no need for Reported-by: Fixes: Closes: tag.
(But a Link: to the thread would be still nice to add)
> mm/slub.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/mm/slub.c b/mm/slub.c
> index f96bac36229c..af942753d495 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -3690,6 +3690,15 @@ static void *alloc_single_from_new_slab(struct kmem_cache *s, struct slab *slab,
> needs_add_partial = (slab->objects > 1);
> build_slab_freelist(s, slab, &iter);
>
> + /*
> + * alloc_debug_processing() still checks @object as a free object
> + * before returning it to the caller. Since @object was emitted
> + * directly from a fresh slab and skipped by build_slab_freelist(), give
> + * it the same next pointer it would have had in the old prebuilt
> + * freelist path.
> + */
This is probably too long ;)
I think one line (something like e.g.,
"/* alloc_debug_processing() always expects a valid free pointer */")
should be enough (and some detail can be included in the changelog
instead)
I was thinking the FP would be NULL but either way looks fine to me.
Thanks for addressing it!
> + set_freepointer(s, object, slab->freelist);
> +
> if (!alloc_debug_processing(s, slab, object, orig_size)) {
> /*
> * It's not really expected that this would fail on a
> --
> 2.25.1
--
Cheers,
Harry / Hyeonggon