All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Zi Yan" <ziy@nvidia.com>
To: "Song Hu" <husong@kylinos.cn>, <akpm@linux-foundation.org>,
	<david@kernel.org>
Cc: <matthew.brost@intel.com>, <joshua.hahnjy@gmail.com>,
	<byungchul@sk.com>, <gourry@gourry.net>,
	<ying.huang@linux.alibaba.com>, <apopple@nvidia.com>,
	<willy@infradead.org>, <shivankg@amd.com>,
	<ridong.chen@linux.dev>, <linux-mm@kvack.org>,
	<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] mm/migrate: don't move memcg NR_FILE_PAGES for swapcache
Date: Mon, 09 Nov 2026 22:09:23 -0500	[thread overview]
Message-ID: <DMR78FJXMD8M.QC57KT5GIPX1@nvidia.com> (raw)
In-Reply-To: <20261104044313.2099309-1-husong@kylinos.cn>

On Tue Nov 3, 2026 at 11:43 PM EST, Song Hu wrote:
> NR_FILE_PAGES lives on both the node and the memcg plane for page
> cache folios: filemap_add_folio() and filemap_unaccount_folio() charge
> it to the folio's node and memcg, while __swap_cache_add_folio() and
> __swap_cache_del_folio() maintain the node plane of NR_FILE_PAGES and
> the memcg plane of NR_SWAPCACHE.  A folio in the swap cache therefore
> carries no per-memcg NR_FILE_PAGES count: shmem folios drop their
> memcg file accounting when swapped out, and anon folios never had any.
>
> The cross-zone arm of __folio_migrate_mapping() moves NR_FILE_PAGES on
> both planes unconditionally.  For swapcache folios the memcg plane is
> empty, so migrating one misaccounts it: the destination accrues
> nr_pages that were never accounted there while the source counter
> underflows.  The wrong counts persist until the memcg is destroyed,
> but the aggregate in memory.stat stays correct, so the drift is easy
> to miss.  NUMA balancing, migratepages, compaction and memory hotplug
> can all migrate such folios.

It would be better to simplify the above like Joshua suggested.

>
> Reproducer, on a 2-node QEMU guest with cgroup v2:
>
>   1. create a cgroup with memory.max = 50M and swap enabled;
>   2. memset 128M of anonymous memory in it, so reclaim swaps most of
>      it out;
>   3. fork to raise the swap entry refcount, then fault the memory
>      back in, so the resident folios are swapcache ones;
>   4. migrate_pages(pid, node0 -> node1).
>
> "file" row of memory.numa_stat (bytes) after step 4:
>
>                     without this patch      with this patch
>                       N0          N1          N0          N1
>                      0 (*)  51691520         0           0
>
>   (*) the source counter has gone negative; negative values read as 0.
>
> Keep moving the node plane via mod_node_page_state() and skip only
> the empty memcg plane, mirroring the swapcache exclusion the NR_SHMEM
> handling in the same block already applies.  It accompanies
> commit 4eef27af2932 ("mm/migrate: move NR_FILE_THPS on cross-node migration")
> and commit c5eef2e03618 ("mm/migrate: move NR_KERNEL_FILE_PAGES on cross-node migration").
>
> Fixes: 0d1c20722ab3 ("mm: memcontrol: switch to native NR_FILE_PAGES and NR_SHMEM counters")
> Signed-off-by: Song Hu <husong@kylinos.cn>
> ---
>  mm/migrate.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/mm/migrate.c b/mm/migrate.c
> index 28a8d7734735..bc60f6587d1b 100644
> --- a/mm/migrate.c
> +++ b/mm/migrate.c
> @@ -690,8 +690,20 @@ static int __folio_migrate_mapping(struct address_space *mapping,
>  		old_lruvec = mem_cgroup_lruvec(memcg, oldzone->zone_pgdat);
>  		new_lruvec = mem_cgroup_lruvec(memcg, newzone->zone_pgdat);
>  
> -		mod_lruvec_state(old_lruvec, NR_FILE_PAGES, -nr);
> -		mod_lruvec_state(new_lruvec, NR_FILE_PAGES, nr);
> +		/*
> +		 * Swapcache folios carry NR_FILE_PAGES on the node plane
> +		 * only (their memcg footprint is NR_SWAPCACHE, see
> +		 * swap_state.c), so move only the node plane for them.
> +		 */
> +		if (folio_test_swapcache(folio)) {
> +			mod_node_page_state(oldzone->zone_pgdat, NR_FILE_PAGES,
> +					    -nr);
> +			mod_node_page_state(newzone->zone_pgdat, NR_FILE_PAGES,
> +					    nr);
> +		} else {
> +			mod_lruvec_state(old_lruvec, NR_FILE_PAGES, -nr);
> +			mod_lruvec_state(new_lruvec, NR_FILE_PAGES, nr);
> +		}

Like Joshua said in another email, it will be more readable if
NR_SWAPCACHE updates can be moved into the then branch above.

>  		if (folio_test_swapbacked(folio) && !folio_test_swapcache(folio)) {
>  			mod_lruvec_state(old_lruvec, NR_SHMEM, -nr);
>  			mod_lruvec_state(new_lruvec, NR_SHMEM, nr);

Anyway,

Acked-by: Zi Yan <ziy@nvidia.com>

-- 
Best Regards,
Yan, Zi


  parent reply	other threads:[~2026-11-10  3:09 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04  4:43 [PATCH] mm/migrate: don't move memcg NR_FILE_PAGES for swapcache Song Hu
2026-11-04 15:54 ` Joshua Hahn
2026-11-05 10:10   ` David Hildenbrand (Arm)
2026-11-06 13:59 ` David Hildenbrand
2026-11-10  3:09 ` Zi Yan [this message]
2026-11-10 12:29   ` David Hildenbrand (Arm)
2026-11-12  2:48     ` Song Hu
2026-11-12  8:54       ` David Hildenbrand (Arm)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DMR78FJXMD8M.QC57KT5GIPX1@nvidia.com \
    --to=ziy@nvidia.com \
    --cc=akpm@linux-foundation.org \
    --cc=apopple@nvidia.com \
    --cc=byungchul@sk.com \
    --cc=david@kernel.org \
    --cc=gourry@gourry.net \
    --cc=husong@kylinos.cn \
    --cc=joshua.hahnjy@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=matthew.brost@intel.com \
    --cc=ridong.chen@linux.dev \
    --cc=shivankg@amd.com \
    --cc=willy@infradead.org \
    --cc=ying.huang@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.