On Mon, Feb 28, 2022 at 05:28:17PM +0100, Marco Elver wrote: > On Mon, Feb 28, 2022 at 03:09PM +0000, Hyeonggon Yoo wrote: > > commit ba10d4b46655 ("mm/slub: use stackdepot to save stack trace in > > objects") initializes stack depot while creating cache if SLAB_STORE_USER > > flag is set. > > > > This can make kernel crash because a cache can be created in various > > contexts. For example if user sets slub_debug=U, kernel crashes > > because create_boot_cache() calls stack_depot_init(), which tries to > > allocate hash table using memblock_alloc() if slab is not available. > > But memblock is also not available at that time. > > > > This patch solves the problem by initializing stack depot early > > in boot process if SLAB_STORE_USER debug flag is set globally > > or the flag is set to at least one cache. > > > > [ elver@xxxxxxxxxx: initialize stack depot depending on slub_debug > > parameter instead of allowing stack_depot_init() can be called > > in kmem_cache_init() for simplicity. ] > > > > Link: https://lkml.org/lkml/2022/2/28/238 > > This would be a better permalink: > https://lore.kernel.org/all/YhyeaP8lrzKgKm5A@xxxxxxxxxxxxxxxxxxx-northeast-1.compute.internal/ > Agreed. > > Fixes: ba10d4b46655 ("mm/slub: use stackdepot to save stack trace in objects") > > This commit does not exist in -next. > It did not land -next yet. > I assume you intend that "lib/stackdepot: Use page allocator if both > slab and memblock is unavailable" should be dropped now. > I did not intend that, but I agree the patch you mentioned should be dropped now. > > Signed-off-by: Hyeonggon Yoo <42.hyeyoo@xxxxxxxxx> > > --- > > include/linux/slab.h | 1 + > > init/main.c | 1 + > > mm/slab.c | 4 ++++ > > mm/slob.c | 4 ++++ > > mm/slub.c | 28 +++++++++++++++++++++++++--- > > 5 files changed, 35 insertions(+), 3 deletions(-) > [...] > > > > +/* Initialize stack depot if needed */ > > +void __init kmem_cache_init_early(void) > > +{ > > +#ifdef CONFIG_STACKDEPOT > > + slab_flags_t block_flags; > > + char *next_block; > > + char *slab_list; > > + > > + if (slub_debug & SLAB_STORE_USER) > > + goto init_stack_depot; > > + > > + next_block = slub_debug_string; > > + while (next_block) { > > + next_block = parse_slub_debug_flags(next_block, &block_flags, &slab_list, false); > > + if (block_flags & SLAB_STORE_USER) > > + goto init_stack_depot; > > + } > > + > > + return; > > + > > +init_stack_depot: > > + stack_depot_init(); > > +#endif > > +} > > You can simplify this function to avoid the goto: > > /* Initialize stack depot if needed */ > void __init kmem_cache_init_early(void) > { > #ifdef CONFIG_STACKDEPOT > slab_flags_t flags = slub_debug; > char *next_block = slub_debug_string; > char *slab_list; > > for (;;) { > if (flags & SLAB_STORE_USER) { > stack_depot_init(); > break; > } > if (!next_block) > break; > next_block = parse_slub_debug_flags(next_block, &flags, &slab_list, false); > } > #endif > } > > ^^ with this version, it'd also be much easier and less confusing to add > other initialization logic unrelated to stackdepot later after the loop > (should it ever be required). Thank you for nice suggestion, but I want to try it in setup_slub_debug() as Vlastimil said! Thanks. -- Thank you, You are awesome! Hyeonggon :-)