[Devel] [PATCH vz10] mm/memcontrol: fix cache counter imbalance in mem_cgroup_replace_folio()

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Thu Jul 24 07:31:38 MSK 2025


note: In vz10 we might lose MEMCG_DATA_PGCACHE flag from folio in:

   +-< commit_charge
     +-< mem_cgroup_replace_folio
     +-< mem_cgroup_migrate

and:

   +-< mem_cgroup_move_account

due to reset "folio->memcg_data", those might also possibly lead to 
cache counter imbalance.

On 7/23/25 23:31, Konstantin Khorenko wrote:
> The function was checking cache flag on the new folio instead of the old one,
> causing cache counter imbalance when replacing cache pages.
> The new folio is freshly allocated and never has the cache flag set, so
> we need to copy the flag from the old folio and charge the cache counter
> accordingly.
> 
> This fixes potential cache accounting issues during page cache replacement
> operations like page migration between NUMA nodes.
> 
> Fixes: 6a2ca4d515c5 ("mm: Memory cgroup page cache limit")
> https://virtuozzo.atlassian.net/browse/VSTOR-111756
> 
> Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
> 
> Feature: mm: Memory cgroup page cache limit
> ---
>   mm/memcontrol.c | 9 ++++++---
>   1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index d0fe610306a0..28f4e518d280 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -5576,6 +5576,12 @@ void mem_cgroup_replace_folio(struct folio *old, struct folio *new)
>   			page_counter_charge(&memcg->memsw, nr_pages);
>   	}
>   
> +	if (folio_memcg_cache(old)) {
> +		WRITE_ONCE(new->memcg_data,
> +			   READ_ONCE(new->memcg_data) | MEMCG_DATA_PGCACHE);
> +		page_counter_charge(&memcg->cache, nr_pages);
> +	}
> +
>   	/*
>   	 * finist explained the idea behind adding a WARN_ON() here:
>   	 * - we do not want to check flags correctness on each flag change
> @@ -5596,9 +5602,6 @@ void mem_cgroup_replace_folio(struct folio *old, struct folio *new)
>   		 folio_test_swapbacked(new)   || folio_test_swapcache(new) ||
>   		 folio_test_mappedtodisk(new) || folio_test_ksm(new)));
>   
> -	if (folio_memcg_cache(new))
> -		page_counter_charge(&memcg->cache, nr_pages);
> -
>   	css_get(&memcg->css);
>   	commit_charge(new, memcg);
>   	memcg1_commit_charge(new, memcg);

-- 
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.



More information about the Devel mailing list