linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Vlastimil Babka <vbabka@suse.cz>
To: kernel test robot <oliver.sang@intel.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Harry Yoo <harry.yoo@oracle.com>,
	Suren Baghdasaryan <surenb@google.com>
Cc: oe-lkp@lists.linux.dev, lkp@intel.com,
	kasan-dev@googlegroups.com, cgroups@vger.kernel.org,
	linux-mm@kvack.org
Subject: Re: [linux-next:master] [slab] db93cdd664: BUG:kernel_NULL_pointer_dereference,address
Date: Wed, 17 Sep 2025 11:18:15 +0200	[thread overview]
Message-ID: <ead41e07-c476-4769-aeb6-5a9950737b98@suse.cz> (raw)
In-Reply-To: <b7d4cf85-5c81-41e0-9b22-baa9a7e5a0c4@suse.cz>

On 9/17/25 10:03, Vlastimil Babka wrote:
> On 9/17/25 07:01, kernel test robot wrote:
>> 
>> 
>> Hello,
>> 
>> kernel test robot noticed "BUG:kernel_NULL_pointer_dereference,address" on:
>> 
>> commit: db93cdd664fa02de9be883dd29343b21d8fc790f ("slab: Introduce kmalloc_nolock() and kfree_nolock().")
>> https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git master
>> 
>> in testcase: boot
>> 
>> config: i386-randconfig-062-20250913
>> compiler: clang-20
>> test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G
>> 
>> (please refer to attached dmesg/kmsg for entire log/backtrace)

Managed to reproduce locally and my suggested fix works so I'm going to fold
it unless there's objections or better suggestions.

Also I was curious to find out which path is triggered so I've put a
dump_stack() before the kmalloc_nolock call:

[    0.731812][    T0] Call Trace:
[    0.732406][    T0]  __dump_stack+0x18/0x30
[    0.733200][    T0]  dump_stack_lvl+0x32/0x90
[    0.734037][    T0]  dump_stack+0xd/0x20
[    0.734780][    T0]  alloc_slab_obj_exts+0x181/0x1f0
[    0.735862][    T0]  __alloc_tagging_slab_alloc_hook+0xd1/0x330
[    0.736988][    T0]  ? __slab_alloc+0x4e/0x70
[    0.737858][    T0]  ? __set_page_owner+0x167/0x280
[    0.738774][    T0]  __kmalloc_cache_noprof+0x379/0x460
[    0.739756][    T0]  ? depot_fetch_stack+0x164/0x180
[    0.740687][    T0]  ? __set_page_owner+0x167/0x280
[    0.741604][    T0]  __set_page_owner+0x167/0x280
[    0.742503][    T0]  post_alloc_hook+0x17a/0x200
[    0.743404][    T0]  get_page_from_freelist+0x13b3/0x16b0
[    0.744427][    T0]  ? kvm_sched_clock_read+0xd/0x20
[    0.745358][    T0]  ? kvm_sched_clock_read+0xd/0x20
[    0.746290][    T0]  ? __next_zones_zonelist+0x26/0x60
[    0.747265][    T0]  __alloc_frozen_pages_noprof+0x143/0x1080
[    0.748358][    T0]  ? lock_acquire+0x8b/0x180
[    0.749209][    T0]  ? pcpu_alloc_noprof+0x181/0x800
[    0.750198][    T0]  ? sched_clock_noinstr+0x8/0x10
[    0.751119][    T0]  ? local_clock_noinstr+0x137/0x140
[    0.752089][    T0]  ? kvm_sched_clock_read+0xd/0x20
[    0.753023][    T0]  alloc_slab_page+0xda/0x150
[    0.753879][    T0]  new_slab+0xe1/0x500
[    0.754615][    T0]  ? kvm_sched_clock_read+0xd/0x20
[    0.755577][    T0]  ___slab_alloc+0xd79/0x1680
[    0.756469][    T0]  ? pcpu_alloc_noprof+0x538/0x800
[    0.757408][    T0]  ? __mutex_unlock_slowpath+0x195/0x3e0
[    0.758446][    T0]  __slab_alloc+0x4e/0x70
[    0.759237][    T0]  ? mm_alloc+0x38/0x80
[    0.759993][    T0]  kmem_cache_alloc_noprof+0x1db/0x470
[    0.760993][    T0]  ? mm_alloc+0x38/0x80
[    0.761745][    T0]  ? mm_alloc+0x38/0x80
[    0.762506][    T0]  mm_alloc+0x38/0x80
[    0.763260][    T0]  poking_init+0xe/0x80
[    0.764032][    T0]  start_kernel+0x16b/0x470
[    0.764858][    T0]  i386_start_kernel+0xce/0xf0
[    0.765723][    T0]  startup_32_smp+0x151/0x160

And the reason is we still have restricted gfp_allowed_mask at this point:
/* The GFP flags allowed during early boot */
#define GFP_BOOT_MASK (__GFP_BITS_MASK & ~(__GFP_RECLAIM|__GFP_IO|__GFP_FS))

It's only lifted to a full allowed mask later in the boot.

That means due to "kmalloc_nolock() is not supported on architectures that
don't implement cmpxchg16b" such architectures will no longer get objexts
allocated in early boot. I guess that's not a big deal.

Also any later allocation having its flags screwed for some reason to not
have __GFP_RECLAIM will also lose its objexts. Hope that's also acceptable.
I don't know if we can distinguish a real kmalloc_nolock() scope in
alloc_slab_obj_exts() without inventing new gfp flags or passing an extra
argument through several layers of functions.

>> 
>> 
>> If you fix the issue in a separate patch/commit (i.e. not just a new version of
>> the same patch/commit), kindly add following tags
>> | Reported-by: kernel test robot <oliver.sang@intel.com>
>> | Closes: https://lore.kernel.org/oe-lkp/202509171214.912d5ac-lkp@intel.com
>> 
>> 
>> [    7.101117][    T0] BUG: kernel NULL pointer dereference, address: 00000010
>> [    7.102290][    T0] #PF: supervisor read access in kernel mode
>> [    7.103219][    T0] #PF: error_code(0x0000) - not-present page
>> [    7.104161][    T0] *pde = 00000000
>> [    7.104762][    T0] Thread overran stack, or stack corrupted
> 
> Note this.
> 
>> [    7.105726][    T0] Oops: Oops: 0000 [#1]
>> [    7.106410][    T0] CPU: 0 UID: 0 PID: 0 Comm: swapper Tainted: G                T   6.17.0-rc3-00014-gdb93cdd664fa #1 NONE  40eff3b43e4f0000b061f2e660abd0b2911f31b1
>> [    7.108712][    T0] Tainted: [T]=RANDSTRUCT
>> [    7.109368][    T0] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
>> [ 7.110952][ T0] EIP: kmalloc_nolock_noprof (mm/slub.c:5607) 
> 
> That's here.
> if (!(s->flags & __CMPXCHG_DOUBLE) && !kmem_cache_debug(s))
> 
> dmesg already contains line "SLUB: HWalign=64, Order=0-3, MinObjects=0,
> CPUs=1, Nodes=1" so all kmem caches are fully initialized, so doesn't look
> like a bootstrap issue. Probably it's due to the stack overflow and not
> actual bug on this line.
> 
> Because of that it's also unable to print the backtrace. But the only
> kmallock_nolock usage for now is in slub itself, alloc_slab_obj_exts():
> 
>         /* Prevent recursive extension vector allocation */
>         gfp |= __GFP_NO_OBJ_EXT;
>         if (unlikely(!allow_spin)) {
>                 size_t sz = objects * sizeof(struct slabobj_ext);
> 
>                 vec = kmalloc_nolock(sz, __GFP_ZERO, slab_nid(slab));
>         } else {
>                 vec = kcalloc_node(objects, sizeof(struct slabobj_ext), gfp,
>                                    slab_nid(slab));
>         }
> 
> Prevent recursive... hm? And we had stack overflow?
> Also .config has CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT=y
> 
> So, this?
> diff --git a/mm/slub.c b/mm/slub.c
> index 837ee037abb5..c4f17ac6e4b6 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -2092,7 +2092,8 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
>  	if (unlikely(!allow_spin)) {
>  		size_t sz = objects * sizeof(struct slabobj_ext);
>  
> -		vec = kmalloc_nolock(sz, __GFP_ZERO, slab_nid(slab));
> +		vec = kmalloc_nolock(sz, __GFP_ZERO | __GFP_NO_OBJ_EXT,
> +				     slab_nid(slab));
>  	} else {
>  		vec = kcalloc_node(objects, sizeof(struct slabobj_ext), gfp,
>  				   slab_nid(slab));
> @@ -5591,7 +5592,8 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node)
>  	bool can_retry = true;
>  	void *ret = ERR_PTR(-EBUSY);
>  
> -	VM_WARN_ON_ONCE(gfp_flags & ~(__GFP_ACCOUNT | __GFP_ZERO));
> +	VM_WARN_ON_ONCE(gfp_flags & ~(__GFP_ACCOUNT | __GFP_ZERO |
> +				      __GFP_NO_OBJ_EXT));
>  
>  	if (unlikely(!size))
>  		return ZERO_SIZE_PTR;
> 



  reply	other threads:[~2025-09-17  9:18 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-17  5:01 kernel test robot
2025-09-17  8:03 ` Vlastimil Babka
2025-09-17  9:18   ` Vlastimil Babka [this message]
2025-09-17 18:38     ` Alexei Starovoitov
2025-09-18  7:06       ` Vlastimil Babka
2025-09-18 14:49         ` Suren Baghdasaryan
2025-09-19  1:39           ` Alexei Starovoitov
2025-09-19 15:01             ` Suren Baghdasaryan
2025-09-19 18:31               ` Alexei Starovoitov
2025-09-26 12:25                 ` Vlastimil Babka
2025-09-26 15:30                   ` Alexei Starovoitov
2025-09-26 15:38                     ` Suren Baghdasaryan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ead41e07-c476-4769-aeb6-5a9950737b98@suse.cz \
    --to=vbabka@suse.cz \
    --cc=ast@kernel.org \
    --cc=cgroups@vger.kernel.org \
    --cc=harry.yoo@oracle.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=linux-mm@kvack.org \
    --cc=lkp@intel.com \
    --cc=oe-lkp@lists.linux.dev \
    --cc=oliver.sang@intel.com \
    --cc=surenb@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox