We observed failures in the 'memcontrol02' test case from the Linux Test Project (LTP) [1] when running on a 256-core server with the 6.6.y kernel. The test fails due to stale memory.stat values being returned, which is caused by the current stats flushing implementation's limitations with large core counts.
This series backports the memcg subtree stats flushing improvements from Linux 6.8 to 6.6.y to address the issue. The main goal is to restore per-memcg stats flushing with dynamic thresholds, which improves both accuracy and performance of memory cgroup statistics, especially on high-core-count systems.
Background ==========
The current stats flushing in 6.6.y flushes the entire memcg hierarchy with a global threshold. This is not efficient and can cause stale stats when read 'memory.stat'.
Dependency Patches ==================
Patches 1-2 are dependencies required for clean application of the main series:
Patch 1: 811244a501b9 "mm: memcg: add THP swap out info for anonymous reclaim"
This patch adds THP_SWPOUT and THP_SWPOUT_FALLBACK entries to the memcg_vm_event_stat[] array. It is needed because patch 4 (e0bf1dc859fd) moves the vmstats struct definitions, including this array. Without this patch, the array structure would not match between 6.6.y and 6.8, causing context conflicts during cherry-pick.
The patch is already in mainline (merged in v6.7) but was not included in the stable 6.6.y branch.
Patch 2: 7108cc3f765c "mm: memcg: add per-memcg zswap writeback stat"
This patch adds the ZSWPWB entry to the memcg_vm_event_stat[] array. Like patch 1, it is required for patch 4 to apply cleanly. The array structure must match the 6.8 state for the code movement to succeed without conflicts.
This patch is also in mainline (merged in v6.8) but was not backported to 6.6.y.
Main Series ===========
Patches 3-7 are the core memcg stats flushing improvements:
- Patch 3: Renames flush_next_time to flush_last_time for clarity - Patch 4: Moves vmstats struct definitions for better code organization - Patch 5: Implements per-memcg stats flushing thresholds (key change) - Patch 6: Moves stats flush into workingset_test_recent() - Patch 7: Restores subtree stats flushing (main feature)
Cherry-Pick Notes for Patch 7 ==============================
Patch 7 (7d7ef0a4686a) requires manual conflict resolution in mm/zswap.c:
The conflict occurs because this patch includes changes to zswap shrinker code that was introduced in Linux 6.8. Since this new shrinker infrastructure does not exist in 6.6.y, the conflicting code should be removed during cherry-pick.
Resolution: Keep the 6.6.y (HEAD) version of mm/zswap.c and discard the new shrinker code from the patch. The conflict markers will show:
<<<<<<< HEAD // existing 6.6.y code ======= // new 6.8 shrinker code (shrink_memcg_cb, zswap_shrinker_scan, etc.)
> 7d7ef0a4686a
Simply keep the HEAD version and remove everything between the "=======" and ">>>>>>>" markers. This is safe because the zswap shrinker is a separate new feature, not a dependency for the memcg stats changes.
Additionally, if you encounter a conflict in mm/workingset.c, it may be due to commit 417dbd7be383 ("mm: ratelimit stat flush from workingset shrinker") which was backported to 6.6.y. The resolution is to use: mem_cgroup_flush_stats_ratelimited(sc->memcg) which preserves the performance optimization while using the new API.
Testing =======
This series has been extensively tested upstream with: - 5000 concurrent workers in 500 cgroups doing allocations and reclaim - 250k threads reading stats every 100ms in 50k cgroups - No performance regressions observed with per-memcg thresholds
The changes improve both stats accuracy and reduce unnecessary flushing overhead.
References ==========
[1] Linux Test Project (LTP): https://github.com/linux-test-project/ltp
Domenico Cerasuolo (1): mm: memcg: add per-memcg zswap writeback stat
Xin Hao (1): mm: memcg: add THP swap out info for anonymous reclaim
Yosry Ahmed (5): mm: memcg: change flush_next_time to flush_last_time mm: memcg: move vmstats structs definition above flushing code mm: memcg: make stats flushing threshold per-memcg mm: workingset: move the stats flush into workingset_test_recent() mm: memcg: restore subtree stats flushing
Documentation/admin-guide/cgroup-v2.rst | 9 + include/linux/memcontrol.h | 8 +- include/linux/vm_event_item.h | 1 + mm/memcontrol.c | 266 +++++++++++++----------- mm/page_io.c | 8 +- mm/vmscan.c | 3 +- mm/vmstat.c | 1 + mm/workingset.c | 42 ++-- mm/zswap.c | 4 + 9 files changed, 203 insertions(+), 139 deletions(-)
-- 2.50.1