From: sashiko-bot@kernel.org
To: "Shakeel Butt" <shakeel.butt@linux.dev>,
"Andrew Morton" <akpm@linux-foundation.org>
Cc: "Dave Chinner" <david@fromorbit.com>,
"Johannes Weiner" <hannes@cmpxchg.org>,
"David Hildenbrand" <david@kernel.org>,
"Michal Hocko" <mhocko@kernel.org>,
"Roman Gushchin" <roman.gushchin@linux.dev>,
"Muchun Song" <muchun.song@linux.dev>,
"Qi Zheng" <qi.zheng@linux.dev>,
"Meta kernel team" <kernel-team@meta.com>,
linux-mm@kvack.org, "Chris Mason" <mason@kernel.org>
Subject: Re: [PATCH] mm: list_lru: fix NULL deref when a folio moves to the root memcg
Date: Fri, 13 Nov 2026 02:42:10 +0000 [thread overview]
Message-ID: <sashiko-outbox-212084@kernel.org> (raw)
In-Reply-To: <20261112024140.648088-1-shakeel.butt@linux.dev>
Thank you for your contribution! Sashiko AI review found no new issues
in this patch, but noticed 1 related pre-existing issue it does not
introduce:
- [High] mm/list_lru: infinite loop in __memcg_list_lru_alloc() on
xas_nomem() failure [1]
--
commit 17fdd494fc11d51fee607883de9cf2593b4f8f83
Author: Shakeel Butt <shakeel.butt@linux.dev>
mm: list_lru: fix NULL deref when a folio moves to the root memcg
This commit skips calling __memcg_list_lru_alloc() in the slow path of
folio_memcg_list_lru_alloc() if the folio's memcg has been reparented to the
root memcg.
> diff --git a/mm/list_lru.c b/mm/list_lru.c
> index d1d256822ccc7..566691ca3dd8f 100644
> --- a/mm/list_lru.c
> +++ b/mm/list_lru.c
> @@ -645,9 +645,15 @@ int folio_memcg_list_lru_alloc(struct folio *folio, struct list_lru *lru,
> if (likely(res))
> return 0;
>
> - /* Allocation may block, pin the memcg */
> + /*
> + * Allocation may block, so pin the memcg. If the folio's cgroup
> + * was removed after the check above, the folio has moved up to a
> + * parent memcg, which can be the root. The root uses the global
> + * lists and has no parent, so skip it.
> + */
> memcg = get_mem_cgroup_from_folio(folio);
> - res = __memcg_list_lru_alloc(memcg, lru, gfp);
> + if (!mem_cgroup_is_root(memcg))
> + res = __memcg_list_lru_alloc(memcg, lru, gfp);
> mem_cgroup_put(memcg);
> return res;
> }
[Severity: High]
This problem wasn't introduced by this patch, but can __memcg_list_lru_alloc()
enter an infinite loop [1] when xas_nomem() fails while populating an
ancestor cgroup?
mm/list_lru.c:__memcg_list_lru_alloc() {
...
do {
pos = memcg;
parent = parent_mem_cgroup(pos);
while (!memcg_list_lru_allocated(parent, lru)) {
pos = parent;
parent = parent_mem_cgroup(pos);
}
...
xas_set(&xas, pos->kmemcg_id);
do {
xas_lock_irqsave(&xas, flags);
if (!xas_load(&xas) && !css_is_dying(&pos->css)) {
xas_store(&xas, mlru);
if (!xas_error(&xas))
mlru = NULL;
}
xas_unlock_irqrestore(&xas, flags);
} while (xas_nomem(&xas, gfp));
} while (pos != memcg && !css_is_dying(&pos->css));
...
return xas_error(&xas);
}
When storing mlru for an ancestor (pos != memcg) needs a new xa_node,
xas_store() sets xas to -ENOMEM and leaves pos unpopulated in lru->xa. If
xas_nomem() then fails to allocate a node (for example under memory pressure,
or when gfp &= GFP_RECLAIM_MASK strips GFP_NOWAIT), it returns false with xas
still in the error state.
Because the outer loop does not check !xas_error(&xas), it repeats for the
same unpopulated ancestor pos, where xas_set() resets xas.xa_node to
XAS_RESTART and clears the error, looping forever and causing a soft or hard
lockup.
[1] https://sashiko.dev/#/bug/linux-21c1dba9-8d6f-4368-b38b-9a57cacb056f
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112024140.648088-1-shakeel.butt@linux.dev?part=1
prev parent reply other threads:[~2026-11-13 2:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 2:41 [PATCH] mm: list_lru: fix NULL deref when a folio moves to the root memcg Shakeel Butt
2026-11-12 2:49 ` Muchun Song
2026-11-12 5:44 ` Shakeel Butt
2026-11-13 2:42 ` sashiko-bot [this message]
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=sashiko-outbox-212084@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=david@fromorbit.com \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=kernel-team@meta.com \
--cc=linux-mm@kvack.org \
--cc=mason@kernel.org \
--cc=mhocko@kernel.org \
--cc=muchun.song@linux.dev \
--cc=qi.zheng@linux.dev \
--cc=roman.gushchin@linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
--cc=shakeel.butt@linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.