Re: [PATCH v2 2/2] mm: multi-gen LRU: fix NULL lruvec->pgdat deref in get_lruvec()
From: Siddharth Chintamaneni
Date: Mon Oct 19 2026 - 16:38:03 EST
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,
> >
> > Fixes: ec1c86b25f4b ("mm: multi-gen LRU: groundwork")
> > Cc: stable@xxxxxxxxxxxxxxx # 6.2+
> > Assisted-by: LLM
> > Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@xxxxxxxxx>
> > Signed-off-by: Hardik Garg <hargar@xxxxxxxxxxxxxxxxxxx>
> > ---
> > mm/vmscan.c | 15 ++-------------
> > 1 file changed, 2 insertions(+), 13 deletions(-)
> >
> > diff --git a/mm/vmscan.c b/mm/vmscan.c
> > index 0c57e4f1eb15..99e9f07fa2e1 100644
> > --- a/mm/vmscan.c
> > +++ b/mm/vmscan.c
> > @@ -2745,20 +2745,9 @@ static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
> > {
> > struct pglist_data *pgdat = NODE_DATA(nid);
> >
> > -#ifdef CONFIG_MEMCG
> > - if (memcg) {
> > - struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec;
> > -
> > - /* see the comment in mem_cgroup_lruvec() */
> > - if (!lruvec->pgdat)
> > - lruvec->pgdat = pgdat;
> > -
> > - return lruvec;
> > - }
> > -#endif
> > - VM_WARN_ON_ONCE(!mem_cgroup_disabled());
> > + VM_WARN_ON_ONCE(!memcg && !mem_cgroup_disabled());
> >
> > - return &pgdat->__lruvec;
> > + return mem_cgroup_lruvec(memcg, pgdat);
> > }
>
> I've been struggling to understand why MGLRU needs its own
> get_lruvec() when mem_cgroup_lruvec() already exists.
> With your patch, it feels like we're one step closer to
> getting rid of MGLRU's own variant in the future.
>
I agree with that! I'm happy to send a follow-up cleanup patch to
remove get_lruvec if that makes sense. Not sure how it will affect
stable backports.
> >
> > static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc)
> > --
> > 2.45.4
>
> Best Regards
> Barry