[PATCH v2 2/2] mm: multi-gen LRU: fix NULL lruvec->pgdat deref in get_lruvec()

From: Siddharth Chintamaneni

Date: Sat Oct 17 2026 - 01:09:39 EST


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.

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);
}

static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc)
--
2.45.4