Re: [PATCH v2 13/28] mm: migrate: prevent memory cgroup release in folio_migrate_mapping()

From: David Hildenbrand (Red Hat)

Date: Tue Dec 30 2025 - 15:08:06 EST


On 12/18/25 15:26, Johannes Weiner wrote:
On Thu, Dec 18, 2025 at 10:09:21AM +0100, David Hildenbrand (Red Hat) wrote:
On 12/17/25 08:27, Qi Zheng wrote:
From: Muchun Song <songmuchun@xxxxxxxxxxxxx>

In the near future, a folio will no longer pin its corresponding
memory cgroup. To ensure safety, it will only be appropriate to
hold the rcu read lock or acquire a reference to the memory cgroup
returned by folio_memcg(), thereby preventing it from being released.

In the current patch, the rcu read lock is employed to safeguard
against the release of the memory cgroup in folio_migrate_mapping().

We usually avoid talking about "patches".

In __folio_migrate_mapping(), the rcu read lock ...


This serves as a preparatory measure for the reparenting of the
LRU pages.

Signed-off-by: Muchun Song <songmuchun@xxxxxxxxxxxxx>
Signed-off-by: Qi Zheng <zhengqi.arch@xxxxxxxxxxxxx>
Reviewed-by: Harry Yoo <harry.yoo@xxxxxxxxxx>
---
mm/migrate.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/mm/migrate.c b/mm/migrate.c
index 5169f9717f606..8bcd588c083ca 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -671,6 +671,7 @@ static int __folio_migrate_mapping(struct address_space *mapping,
struct lruvec *old_lruvec, *new_lruvec;
struct mem_cgroup *memcg;
+ rcu_read_lock();
memcg = folio_memcg(folio);

In general, LGTM

I wonder, though, whether we should embed that in the ABI.

Like "lock RCU and get the memcg" in one operation, to the "return memcg
and unock rcu" in another operation.

Something like "start / end" semantics.

The advantage of open-coding this particular one is that 1)
rcu_read_lock() is something the caller could already be
holding/using, implicitly or explicitly; and 2) it's immediately
obvious that this is an atomic section (which was already useful in
spotting a bug in the workingset patch of this series).

"start/end" terminology hides this. "lock" we can't use because it
would suggest binding stability. The only other idea I'd have would be
to spell it all out:

memcg = folio_memcg_rcu_read_lock(folio);
stuff(memcg);
otherstuff();
rcu_read_unlock();

But that might not be worth it. Maybe somebody can think of a better
name. But I'd be hesitant to trade off the obviousness of what's going
on given how simple the locking + access scheme is.

I rather disagree that open-coding it is the better approach here, in particular when it comes to new users or code changes in the future -- just way, way easier to mess up.

Well, unless we have some other way to add safety-checks that the right locks are held when the memcg is getting used (e.g., passed into other functions). Maybe that is done already to minimize the chance for UAF etc.

I agree that naming is tricky, and that it needs some more thought, so I'm fine with keeping it as is.

--
Cheers

David