From: Usama Arif <usama.arif@linux.dev>
To: Alexandre Ghiti <alex@ghiti.fr>
Cc: Usama Arif <usama.arif@linux.dev>,
Johannes Weiner <hannes@cmpxchg.org>,
Yosry Ahmed <yosry@kernel.org>, Nhat Pham <nphamcs@gmail.com>,
Chengming Zhou <chengming.zhou@linux.dev>,
Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
Vlastimil Babka <vbabka@kernel.org>,
Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>, Hugh Dickins <hughd@google.com>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
Chris Li <chrisl@kernel.org>, Kairui Song <kasong@tencent.com>,
Kemeng Shi <shikemeng@huaweicloud.com>,
Baoquan He <baoquan.he@linux.dev>, Barry Song <baohua@kernel.org>,
Youngjun Park <youngjun.park@lge.com>,
Qi Zheng <qi.zheng@linux.dev>,
Shakeel Butt <shakeel.butt@linux.dev>,
Axel Rasmussen <axelrasmussen@google.com>,
Yuanchu Xie <yuanchu@google.com>, Wei Xu <weixugc@google.com>,
Joonsoo Kim <iamjoonsoo.kim@lge.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 2/3] mm/swap: refault on swap-in, not in the swap cache allocator
Date: Wed, 26 Aug 2026 06:31:28 -0700 [thread overview]
Message-ID: <20260826133130.806177-1-usama.arif@linux.dev> (raw)
In-Reply-To: <20260825172604.3243589-3-alex@ghiti.fr>
On Tue, 25 Aug 2026 19:24:52 +0200 Alexandre Ghiti <alex@ghiti.fr> wrote:
> The swap cache allocator evaluates the refault of every folio it
> allocates. zswap writeback also allocates through it: the shrinker puts
> a buffer folio in the swap cache to write the compressed data out, and
> that allocation is then counted as an anon refault (and, if the eviction
> looks recent, as an activation) even though nothing faulted the page
> back in. On a workload that writes back continuously this inflates
> workingset_refault_anon and workingset_activate_anon substantially.
>
> Move the refault evaluation out of the allocator and into the two
> swap-in callers, which read the slot's shadow before the allocation
> overwrites it. zswap writeback keeps allocating the buffer, but no
> longer reports a refault for it.
>
> The refault is evaluated before folio_add_lru(), as it was before this
> patch, so workingset_refault() still sets PG_workingset/PG_active while
> the folio is off the LRU: folio_add_lru() consumes both when it picks
> the LRU list, and under MGLRU when it picks the generation.
>
> Fixes: aae466b0052e ("mm/swap: implement workingset detection for anonymous LRU")
> Signed-off-by: Nhat Pham <nphamcs@gmail.com>
> Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
> ---
> mm/swap_state.c | 20 ++++++++++++++++++--
> 1 file changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/mm/swap_state.c b/mm/swap_state.c
> index bf8ff2d2dbf1..8046fea015c9 100644
> --- a/mm/swap_state.c
> +++ b/mm/swap_state.c
> @@ -483,8 +483,6 @@ static struct folio *__swap_cache_alloc(struct swap_cluster_info *ci,
>
> /* memsw uncharges swap when folio is added to swap cache */
> memcg1_swapin(folio);
> - if (shadow)
> - workingset_refault(folio, shadow);
>
> node_stat_mod_folio(folio, NR_FILE_PAGES, nr_pages);
> lruvec_stat_mod_folio(folio, NR_SWAPCACHE, nr_pages);
> @@ -646,17 +644,26 @@ static struct folio *swap_cache_read_folio(struct swap_io_ctx *ctx,
> pgoff_t ilx, bool readahead)
> {
> struct folio *folio;
> + void *shadow = NULL;
>
> do {
> folio = swap_cache_get_folio(entry);
> if (folio)
> return folio;
> + /*
> + * Capture the slot's shadow before the allocation overwrites it,
> + * so a fresh swap-in can be evaluated as a refault below.
> + */
> + shadow = swap_cache_get_shadow(entry);
> folio = __swap_cache_alloc_folio(entry, gfp, BIT(0), NULL, mpol, ilx);
Can this refault against a shadow from a different cache generation?
Another swap-in can replace this value, reclaim its folio, and install
a newer shadow while this caller is allocating. This caller can then
win the locked insertion but still use the older snapshot.
What I think should be done here is have an optional shadow output to
__swap_cache_alloc_folio() and return the value captured by the successful
__swap_cache_add_check() under ci->lock and se that output in the swap-in
path?
> } while (PTR_ERR(folio) == -EEXIST);
>
> if (IS_ERR_OR_NULL(folio))
> return NULL;
>
> + if (shadow)
> + workingset_refault(folio, shadow);
> +
> folio_add_lru(folio);
> swap_read_folio(ctx, folio);
> if (readahead) {
> @@ -688,17 +695,26 @@ struct folio *swapin_sync(swp_entry_t entry, gfp_t gfp, unsigned long orders,
> {
> struct swap_io_ctx ctx = {};
> struct folio *folio;
> + void *shadow = NULL;
>
> do {
> folio = swap_cache_get_folio(entry);
> if (folio)
> return folio;
> + /*
> + * Capture the slot's shadow before the allocation overwrites it,
> + * so a fresh swap-in can be evaluated as a refault below.
> + */
> + shadow = swap_cache_get_shadow(entry);
> folio = __swap_cache_alloc_folio(entry, gfp, orders, vmf, mpol, ilx);
> } while (PTR_ERR(folio) == -EEXIST);
>
> if (IS_ERR(folio))
> return folio;
>
> + if (shadow)
> + workingset_refault(folio, shadow);
> +
> folio_add_lru(folio);
> swap_read_folio(&ctx, folio);
> swap_read_submit(&ctx);
> --
> 2.53.0-Meta
>
>
next prev parent reply other threads:[~2026-08-26 13:31 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-25 17:24 [PATCH v3 0/3] mm: fix workingset refaults in the zswap writeback path Alexandre Ghiti
2026-08-25 17:24 ` [PATCH v3 1/3] mm/swap: move LRU insertion out of the swap cache allocator Alexandre Ghiti
2026-08-26 13:21 ` Usama Arif
2026-08-26 15:23 ` Alexandre Ghiti
2026-08-25 17:24 ` [PATCH v3 2/3] mm/swap: refault on swap-in, not in " Alexandre Ghiti
2026-08-26 13:31 ` Usama Arif [this message]
2026-08-26 15:22 ` Alexandre Ghiti
2026-08-25 17:24 ` [PATCH v3 3/3] mm/zswap: preserve the workingset shadow across writeback Alexandre Ghiti
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=20260826133130.806177-1-usama.arif@linux.dev \
--to=usama.arif@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=axelrasmussen@google.com \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=baoquan.he@linux.dev \
--cc=chengming.zhou@linux.dev \
--cc=chrisl@kernel.org \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=hughd@google.com \
--cc=iamjoonsoo.kim@lge.com \
--cc=kasong@tencent.com \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=nphamcs@gmail.com \
--cc=qi.zheng@linux.dev \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=shikemeng@huaweicloud.com \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=weixugc@google.com \
--cc=yosry@kernel.org \
--cc=youngjun.park@lge.com \
--cc=yuanchu@google.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.