* [merged mm-stable] mm-memcg-clear-folio-memcg-after-changing-per-memcg-stats.patch removed from -mm tree
@ 2026-10-09 5:58 Andrew Morton
0 siblings, 0 replies; only message in thread
From: Andrew Morton @ 2026-10-09 5:58 UTC (permalink / raw)
To: mm-commits, yuanchu, weixugc, stable, shikemeng, shakeel.butt,
nphamcs, mhocko, ljs, kasong, hannes, david, chrisl, baoquan.he,
baohua, axelrasmussen, bingfangguo, akpm
The quilt patch titled
Subject: mm/memcg: clear folio memcg after changing per memcg stats
has been removed from the -mm tree. Its filename was
mm-memcg-clear-folio-memcg-after-changing-per-memcg-stats.patch
This patch was dropped because it was merged into the mm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Bingfang Guo <bingfangguo@tencent.com>
Subject: mm/memcg: clear folio memcg after changing per memcg stats
Date: Thu, 10 Sep 2026 11:46:58 +0800
I notice extremely high swapcached count in the per memcg level
memory.stat when running tests with cgroupv1 setup by swapping pages in
and out. It seems that the counter never gets decreased so the value is
rather useless and confusing to users reading it. So I think fixing it so
that the value can reflect the actual swapcache usage correctly could be
helpful.
__memcg1_swapout() transfers the memsw charge of a folio to its swap entry
and clears folio->memcg_data as part of that. In the vmscan swapout path
it runs before __swap_cache_del_folio(), which then decrements the
swapcache stats through lruvec_stat_mod_folio(). Since folio->memcg_data
has already been cleared, folio_memcg() returns NULL and the NR_SWAPCACHE
decrement only updates the node-level counter instead of the memcg's
lruvec, leaking the per-memcg swapcache count.
Users using swaps will read totally meaningless swapcache value from
per memcg memory.stat, like 200GB of swapcache on a 64GB setup, which
is quite confusing and may trigger monitoring alerts, if any.
Move the __memcg1_swapout() call into __swap_cache_del_folio(), after the
NR_FILE_PAGES and NR_SWAPCACHE updates but before
__swap_cache_do_del_folio() removes the folio from the swap cache. This
keeps the stats attributed to the folio's memcg while still recording the
swap cgroup with a valid folio->swap. Add a swapout parameter so the
plain swap_cache_del_folio() path is left unchanged.
Link: https://lore.kernel.org/20260910-memcg-swapcache-stats-fix-v5-1-033f510ba748@tencent.com
Fixes: 2732acda82c9 ("mm, swap: use swap cache as the swap in synchronize layer")
Signed-off-by: Bingfang Guo <bingfangguo@tencent.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Kairui Song <kasong@tencent.com>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Barry Song <baohua@kernel.org>
Cc: Chris Li <chrisl@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Wei Xu <weixugc@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: <stable@vger.kernel.org>
---
mm/swap.h | 6 ++++--
mm/swap_state.c | 13 ++++++++++---
mm/vmscan.c | 3 +--
3 files changed, 15 insertions(+), 7 deletions(-)
--- a/mm/swap.h~mm-memcg-clear-folio-memcg-after-changing-per-memcg-stats
+++ a/mm/swap.h
@@ -319,7 +319,8 @@ struct folio *swap_cache_alloc_folio(swp
void __swap_cache_add_folio(struct swap_cluster_info *ci,
struct folio *folio, swp_entry_t entry);
void __swap_cache_del_folio(struct swap_cluster_info *ci,
- struct folio *folio, swp_entry_t entry, void *shadow);
+ struct folio *folio, swp_entry_t entry, void *shadow,
+ bool swapout);
void __swap_cache_replace_folio(struct swap_cluster_info *ci,
struct folio *old, struct folio *new);
@@ -452,7 +453,8 @@ static inline void swap_cache_del_folio(
}
static inline void __swap_cache_del_folio(struct swap_cluster_info *ci,
- struct folio *folio, swp_entry_t entry, void *shadow)
+ struct folio *folio, swp_entry_t entry, void *shadow,
+ bool swapout)
{
}
--- a/mm/swap_state.c~mm-memcg-clear-folio-memcg-after-changing-per-memcg-stats
+++ a/mm/swap_state.c
@@ -306,21 +306,28 @@ static void __swap_cache_do_del_folio(st
* @folio: The folio.
* @entry: The first swap entry that the folio corresponds to.
* @shadow: shadow value to be filled in the swap cache.
+ * @swapout: whether this folio is being reclaimed after swapout.
*
* Removes a folio from the swap cache and fills a shadow in place.
* This won't put the folio's refcount. The caller has to do that.
*
* Context: Caller must ensure the folio is locked and in the swap cache
* using the index of @entry, and lock the cluster that holds the entries.
+ * If @swapout is set, the folio should be in reclaim path and IRQs
+ * should be disabled.
*/
void __swap_cache_del_folio(struct swap_cluster_info *ci, struct folio *folio,
- swp_entry_t entry, void *shadow)
+ swp_entry_t entry, void *shadow, bool swapout)
{
unsigned long nr_pages = folio_nr_pages(folio);
- __swap_cache_do_del_folio(ci, folio, entry, shadow);
node_stat_mod_folio(folio, NR_FILE_PAGES, -nr_pages);
lruvec_stat_mod_folio(folio, NR_SWAPCACHE, -nr_pages);
+
+ if (swapout)
+ __memcg1_swapout(folio, ci);
+
+ __swap_cache_do_del_folio(ci, folio, entry, shadow);
}
/**
@@ -339,7 +346,7 @@ void swap_cache_del_folio(struct folio *
swp_entry_t entry = folio->swap;
ci = swap_cluster_lock(__swap_entry_to_info(entry), swp_offset(entry));
- __swap_cache_del_folio(ci, folio, entry, NULL);
+ __swap_cache_del_folio(ci, folio, entry, NULL, false);
swap_cluster_unlock(ci);
folio_ref_sub(folio, folio_nr_pages(folio));
--- a/mm/vmscan.c~mm-memcg-clear-folio-memcg-after-changing-per-memcg-stats
+++ a/mm/vmscan.c
@@ -807,8 +807,7 @@ static int __remove_mapping(struct addre
if (reclaimed && !mapping_exiting(mapping))
shadow = workingset_eviction(folio, target_memcg);
- __memcg1_swapout(folio, ci);
- __swap_cache_del_folio(ci, folio, swap, shadow);
+ __swap_cache_del_folio(ci, folio, swap, shadow, true);
swap_cluster_unlock_irq(ci);
} else {
void (*free_folio)(struct folio *);
_
Patches currently in -mm which might be from bingfangguo@tencent.com are
memcg-keep-swap-charging-under-rcu-protection.patch
memcg-base-swap-charge-accounting-on-memcgid-root-status.patch
memcg-manipulate-memcg-private-id-references-by-id.patch
memcg-move-memcg-private-id-refcount-to-objcg.patch
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-09 5:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-09 5:58 [merged mm-stable] mm-memcg-clear-folio-memcg-after-changing-per-memcg-stats.patch removed from -mm tree Andrew Morton
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.