From: Cao Ruichuang <create0818@163.com>
To: Johannes Weiner <hannes@cmpxchg.org>,
Michal Hocko <mhocko@kernel.org>,
Roman Gushchin <roman.gushchin@linux.dev>,
Shakeel Butt <shakeel.butt@linux.dev>
Cc: Muchun Song <muchun.song@linux.dev>,
Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>,
"Liam R. Howlett" <Liam.Howlett@oracle.com>,
Vlastimil Babka <vbabka@kernel.org>,
Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
cgroups@vger.kernel.org, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, Cao Ruichuang <create0818@163.com>,
syzbot+1a3353a77896e73a8f53@syzkaller.appspotmail.com
Subject: [PATCH] mm/memcontrol: restore irq wrapper for lruvec_stat_mod_folio()
Date: Mon, 13 Apr 2026 14:48:33 +0800 [thread overview]
Message-ID: <20260413064833.964-1-create0818@163.com> (raw)
Commit c1bd09994c4d ("memcg: remove __lruvec_stat_mod_folio") removed
the local_irq_save/restore wrapper around lruvec_stat_mod_folio(), based
on the assumption that the underlying stat update path was already
IRQ-safe.
That assumption is too broad for lruvec_stat_mod_folio() callers.
This helper is not just a thin stat primitive. It also resolves
folio -> memcg -> lruvec under a helper-managed RCU read-side section.
syzbot now reports a PREEMPT_RT warning from:
__filemap_add_folio()
-> lruvec_stat_mod_folio()
-> __rcu_read_unlock()
ending in bad unlock balance / negative RCU nesting.
The PREEMPT_RT detail matters here. The affected filemap path calls
lruvec_stat_mod_folio() under xas_lock_irq(), but on PREEMPT_RT
xas_lock_irq() maps to spin_lock_irq(), and spin_lock_irq() does not
disable hard IRQs. Before c1bd09994c4d, lruvec_stat_mod_folio() still
provided explicit hard-IRQ masking around the folio-based memcg/lruvec
lookup path. After that commit, those callers no longer get real
hard-IRQ masking from either the xarray lock or the helper itself.
Direct mod_lruvec_state() callers do not have the same problem surface:
they already operate on a stable lruvec under caller-provided locking or
caller-provided RCU coverage. The narrower regression boundary is the
folio-based helper that combines ownership lookup with helper-managed
RCU. Restore only that helper's irq wrapper instead of reverting the
lower-level lruvec state update cleanups.
This restores the previous calling contract for lruvec_stat_mod_folio()
without changing the lower-level lruvec state interfaces.
Fixes: c1bd09994c4d ("memcg: remove __lruvec_stat_mod_folio")
Link: https://syzkaller.appspot.com/bug?extid=1a3353a77896e73a8f53
Reported-by: syzbot+1a3353a77896e73a8f53@syzkaller.appspotmail.com
Signed-off-by: Cao Ruichuang <create0818@163.com>
---
include/linux/vmstat.h | 18 +++++++++++++++++-
mm/memcontrol.c | 4 ++--
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 3c9c266cf78..59cf2676649 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -519,9 +519,19 @@ static inline const char *vm_event_name(enum vm_event_item item)
void mod_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx,
int val);
-void lruvec_stat_mod_folio(struct folio *folio,
+void __lruvec_stat_mod_folio(struct folio *folio,
enum node_stat_item idx, int val);
+static inline void lruvec_stat_mod_folio(struct folio *folio,
+ enum node_stat_item idx, int val)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __lruvec_stat_mod_folio(folio, idx, val);
+ local_irq_restore(flags);
+}
+
static inline void mod_lruvec_page_state(struct page *page,
enum node_stat_item idx, int val)
{
@@ -536,6 +546,12 @@ static inline void mod_lruvec_state(struct lruvec *lruvec,
mod_node_page_state(lruvec_pgdat(lruvec), idx, val);
}
+static inline void __lruvec_stat_mod_folio(struct folio *folio,
+ enum node_stat_item idx, int val)
+{
+ mod_node_page_state(folio_pgdat(folio), idx, val);
+}
+
static inline void lruvec_stat_mod_folio(struct folio *folio,
enum node_stat_item idx, int val)
{
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 772bac21d15..ffe6ae885f5 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -787,7 +787,7 @@ void mod_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx,
mod_memcg_lruvec_state(lruvec, idx, val);
}
-void lruvec_stat_mod_folio(struct folio *folio, enum node_stat_item idx,
+void __lruvec_stat_mod_folio(struct folio *folio, enum node_stat_item idx,
int val)
{
struct mem_cgroup *memcg;
@@ -807,7 +807,7 @@ void lruvec_stat_mod_folio(struct folio *folio, enum node_stat_item idx,
mod_lruvec_state(lruvec, idx, val);
rcu_read_unlock();
}
-EXPORT_SYMBOL(lruvec_stat_mod_folio);
+EXPORT_SYMBOL(__lruvec_stat_mod_folio);
void mod_lruvec_kmem_state(void *p, enum node_stat_item idx, int val)
{
--
2.39.5 (Apple Git-154)
next reply other threads:[~2026-04-13 6:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-13 6:48 Cao Ruichuang [this message]
2026-04-13 16:44 ` [PATCH] mm/memcontrol: restore irq wrapper for lruvec_stat_mod_folio() Shakeel Butt
2026-04-14 7:56 ` Vlastimil Babka (SUSE)
2026-04-15 16:22 ` create0818
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=20260413064833.964-1-create0818@163.com \
--to=create0818@163.com \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=cgroups@vger.kernel.org \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@kernel.org \
--cc=muchun.song@linux.dev \
--cc=roman.gushchin@linux.dev \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=surenb@google.com \
--cc=syzbot+1a3353a77896e73a8f53@syzkaller.appspotmail.com \
--cc=vbabka@kernel.org \
/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.