Re: [PATCH v2 2/2] mm: multi-gen LRU: fix NULL lruvec->pgdat deref in get_lruvec()
From: Barry Song
Date: Mon Oct 19 2026 - 20:43:33 EST
On Tue, Oct 20, 2026 at 8:16 AM Siddharth Chintamaneni
<sidchintamaneni@xxxxxxxxx> wrote:
>
> On Mon, 19 Oct 2026 at 16:36, Barry Song <baohua@xxxxxxxxxx> wrote:
> >
> > On Tue, Oct 20, 2026 at 4:33 AM Siddharth Chintamaneni
> > <sidchintamaneni@xxxxxxxxx> wrote:
> > >
> > > On Sun, 18 Oct 2026 at 14:24, Barry Song <baohua@xxxxxxxxxx> wrote:
> > > >
> > > > On Sat, Oct 17, 2026 at 1:09 PM Siddharth Chintamaneni
> > > > <sidchintamaneni@xxxxxxxxx> wrote:
> > > > >
> > > > > Andrew Morton reported that get_lruvec() has the same problem as
> > > > > lru_gen_shrink_node(): when memcg is disabled on the command line
> > > > > (cgroup_disable=memory), it returns &pgdat->__lruvec directly and so
> > > > > bypasses the initialization of lruvec->pgdat. The MGLRU debugfs
> > > > > interface calls get_lruvec(), then dereferences the pgdat pointer in
> > > > > lru_gen_seq_show() and other paths, so these can hit the same NULL
> > > > > dereference.
> > > >
> > > > So userspace must have booted, since otherwise we couldn't read
> > > > debugfs. The reachable case is therefore a memory node with no
> > > > LRU folios when debugfs is read? So this could happen on a multi-node
> > > > system where folios are landed on other nodes but not on this node?
> > > >
> > >
> > > That is my high level understanding. I'll let Andrew to comment if I
> > > am missing something,
> > >
> >
> > I made a silly toy setup by running two numa nodes with one of them has only 4KB
> > memory, the other one has 1G-4K:
> >
> > qemu-system-aarch64 -M virt,gic-version=3,mte=off -cpu cortex-a53 -nographic \
> > -smp 4 \
> > -m 1G \
> > -object memory-backend-ram,id=ram0,size=1048572K \
> > -object memory-backend-ram,id=ram1,size=4K \
> > -numa node,nodeid=0,memdev=ram0,cpus=0-1 \
> > -numa node,nodeid=1,memdev=ram1,cpus=2-3 \
> > -kernel arch/arm64/boot/Image \
> > -nographic -append "cgroup_disable=memory
> > ...
> >
> > Then I got a machine where node1 is very difficult to have a page in lru.
> >
> > then i ran the debugfs for mglru:
> >
> > / # cat /sys/kernel/debug/lru_gen
> > memcg 0
> > node 0
> > 0 14972 0 953
> > 1 14972 0 1
> > 2 14972 18 3308
> > 3 14972 0 0
> > node 1
> > 0 14972 0 0
> > 1 14972 0 0
> > 2 14972 0 0
> > 3 14972 0 0
> >
> > now you see node 1 has no page in lru but yet i didn't have any crash.
> >
> > i think i will need more time to figure out what is the problem and how to
> > reproduce it.
>
> I've asked AI to repro the issue with the similar setup
>
> qemu-system-aarch64 -M virt,gic-version=3,mte=off -cpu cortex-a53 -nographic \
> -smp 4 -m 1G \
> -object memory-backend-ram,id=ram0,size=1048512K \
> -object memory-backend-ram,id=ram1,size=64K \
> -numa node,nodeid=0,memdev=ram0,cpus=0-1 \
> -numa node,nodeid=1,memdev=ram1,cpus=2-3 \
> -kernel "$KERNEL" \
> -initrd "$INITRD" \
> -no-reboot \
> -append "console=ttyAMA0 cgroup_disable=memory
> initcall_blacklist=kswapd_init panic=-1"
>
> and it was able to repo it. AI identified that kswapd is initializing
> the pgdat during boot, so blacklisting kswap_init was able to repro
> the crash when reading /sys/kernel/debug/lru_gen
Thanks!
I guess you mean the following:
-module_init(kswapd_init)
+//module_init(kswapd_init)
Yes, I can reproduce it with the above as well.
But kswapd_init() is definitely called before we enter userspace,
so this doesn't seem to be an issue here?
So I feel there is no bug here, but this cleanup is still welcome.
Am I missing any other scenarios?
Best Regards
Barry