mm-mglru-fix-stale-batch-updates-after-memcg-reparenting.patch removed from -mm tree
The quilt patch titled
Subject: mm: mglru: fix stale batch updates after memcg reparenting
has been removed from the -mm tree. Its filename was
mm-mglru-fix-stale-batch-updates-after-memcg-reparenting.patch
This patch was dropped because it was merged into the mm-hotfixes-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Qi Zheng <[email protected]>
Subject: mm: mglru: fix stale batch updates after memcg reparenting
Date: Fri, 10 Jul 2026 23:43:18 +0800
The mglru page table walker batches per-generation size deltas in walk->nr_pages while walking page tables without holding the lruvec lock. The reset_batch_size() later folds those deltas into walk->lruvec under the lruvec lock.
The page table walker can run concurrently with the memcg reparenting path as follows:
CPU0 CPU1
==== ====
walk_mm
--> walk_page_range
--> update_batch_size
--> walk->nr_pages += delta
mem_cgroup_css_offline
--> memcg_reparent_objcgs
--> lock lruvec
lru_gen_reparent_memcg
--> reparent child folios to parent
unlock lruvec
lock lruvec
reset_batch_size
--> child lrugen->nr_pages += deltaThis will trigger the following warning in lru_gen_exit_memcg():
VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0, sizeof(lruvec->lrugen.nr_pages)));
And the user-visible impact of underestimated nr_pages in MGLRU was premature OOMs because MGLRU does not try to reclaim memory when nr_pages reaches zero, but there are still more pages.
To fix it, make reset_batch_size() check CSS_DYING under RCU before flushing the pending batch. A non-dying memcg keeps the original lruvec stable against RCU-delayed offlining; a dying memcg redirects the deltas to the first non-dying ancestor.
---
include/linux/memcontrol.h | 25 +++++++++++++++++++++++++ mm/vmscan.c | 11 ++++------- 2 files changed, 29 insertions(+), 7 deletions(-)
include/linux/memcontrol.h renamed from include/linux/memcontrol.h~mm-mglru-fix-stale-batch-updates-after-memcg-reparenting +25 -0
@@ -1472,6 +1472,31 @@ static inline void lruvec_lock_irq(strucspin_lock_irq (&lruvec->lru_lock); } +static inline struct lruvec *lruvec_live_lock_irq (struct lruvec *lruvec) +{ +#ifdef CONFIG_MEMCG +struct pglist_data *pgdat =lruvec_pgdat (lruvec); +struct mem_cgroup *memcg =lruvec_memcg (lruvec); + +rcu_read_lock (); + +/* +* The memcg can be NULL when the memory controller is disabled. +* Otherwise, the caller keeps the memcg owning @lruvec alive. +*/ +while (unlikely (memcg &&css_is_dying (&memcg->css))) { + memcg =parent_mem_cgroup (memcg); + lruvec =mem_cgroup_lruvec (memcg, pgdat); + } + +spin_lock_irq (&lruvec->lru_lock); +#else +lruvec_lock_irq (lruvec); +#endif + +return lruvec; +} +static inline void lruvec_unlock (struct lruvec *lruvec) {spin_unlock (&lruvec->lru_lock);
mm/vmscan.c renamed from mm/vmscan.c~mm-mglru-fix-stale-batch-updates-after-memcg-reparenting +4 -7
@@ -3265,7 +3265,7 @@ static void update_batch_size(struct lrustatic void reset_batch_size (struct lru_gen_mm_walk *walk) {int gen, type, zone; -struct lruvec *lruvec = walk->lruvec; +struct lruvec *lruvec =lruvec_live_lock_irq (walk->lruvec);struct lru_gen_folio *lrugen = &lruvec->lrugen; walk->batched =0 ;
@@ -3285,6 +3285,8 @@ static void reset_batch_size(struct lru_ lru +=LRU_ACTIVE ;__update_lru_size (lruvec, lru, zone, delta); } + +lruvec_unlock_irq (lruvec); }static int should_skip_vma (unsigned long start,unsigned long end,struct mm_walk *args)
@@ -3779,11 +3781,8 @@ static void walk_mm(struct mm_struct *mmmmap_read_unlock (mm); } -if (walk->batched) { -lruvec_lock_irq (lruvec); +if (walk->batched)reset_batch_size (walk); -lruvec_unlock_irq (lruvec); - }cond_resched (); }while (err == -EAGAIN );
@@ -4867,9 +4866,7 @@ retry: walk = current->reclaim_state->mm_walk;if (walk && walk->batched) { walk->lruvec = lruvec; -lruvec_lock_irq (lruvec);reset_batch_size (walk); -lruvec_unlock_irq (lruvec); } mod_lruvec_state(lruvec, PGDEMOTE_KSWAPD + reclaimer_offset(sc),
_
Patches currently in -mm which might be from [email protected] are