From: Kairui Song <ryncsn@gmail.com>
To: Alexandre Ghiti <alex@ghiti.fr>
Cc: Johannes Weiner <hannes@cmpxchg.org>,
Yosry Ahmed <yosry@kernel.org>, Nhat Pham <nphamcs@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
Chris Li <chrisl@kernel.org>, Kairui Song <kasong@tencent.com>,
Chengming Zhou <chengming.zhou@linux.dev>,
"Matthew Wilcox (Oracle)" <willy@infradead.org>,
Jan Kara <jack@suse.cz>, Kemeng Shi <shikemeng@huaweicloud.com>,
Baoquan He <baoquan.he@linux.dev>,
Barry Song <baohua@kernel.org>,
Youngjun Park <youngjun.park@lge.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 1/2] mm: zswap: free synchronous-IO writeback folios directly
Date: Sat, 18 Jul 2026 19:10:03 +0800 [thread overview]
Message-ID: <altSA1zXhzvHPJYe@KASONG-MC4> (raw)
In-Reply-To: <20260718093723.153324-2-alex@ghiti.fr>
On Sat, Jul 18, 2026 at 11:36:39AM +0800, Alexandre Ghiti wrote:
> When zswap writes an entry back, it allocates a swap cache folio,
> decompresses the entry into it and writes it out. That folio is cold by
> construction, but it is currently left on the LRU for page reclaim to find
> and free later. This wastes a reclaim scan and keeps cold memory resident
> longer than necessary.
>
> For synchronous-IO swap devices writeback completes in the calling context,
> so the folio can be freed right after the write rather than left behind; do
> that. Because it is freed directly rather than through reclaim, it is
> allocated off the LRU: dropping the last reference on a folio still on the
> LRU would trip the free-time page-flag checks. A folio that a concurrent
> swapin has meanwhile claimed is left in place and reclaimed as usual.
>
> Asynchronous and filesystem-backed swap complete writeback in interrupt
> context, where the folio cannot be freed; they are handled in a later
> change.
>
> Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
> ---
> mm/swap.h | 3 ++-
> mm/swap_state.c | 17 +++++++++++------
> mm/zswap.c | 36 ++++++++++++++++++++++++++++++++++--
> 3 files changed, 47 insertions(+), 9 deletions(-)
>
> diff --git a/mm/swap.h b/mm/swap.h
> index 77d2d14eda42..c617e5a0257f 100644
> --- a/mm/swap.h
> +++ b/mm/swap.h
> @@ -306,7 +306,8 @@ void *swap_cache_get_shadow(swp_entry_t entry);
> void swap_cache_del_folio(struct folio *folio);
> struct folio *swap_cache_alloc_folio(swp_entry_t target_entry, gfp_t gfp_mask,
> unsigned long orders, struct vm_fault *vmf,
> - struct mempolicy *mpol, pgoff_t ilx);
> + struct mempolicy *mpol, pgoff_t ilx,
> + bool skip_lru);
> /* Below helpers require the caller to lock and pass in the swap cluster. */
> void __swap_cache_add_folio(struct swap_cluster_info *ci,
> struct folio *folio, swp_entry_t entry);
> diff --git a/mm/swap_state.c b/mm/swap_state.c
> index 9c3a5cf99778..048efc7ca612 100644
> --- a/mm/swap_state.c
> +++ b/mm/swap_state.c
> @@ -403,7 +403,8 @@ void __swap_cache_replace_folio(struct swap_cluster_info *ci,
> static struct folio *__swap_cache_alloc(struct swap_cluster_info *ci,
> swp_entry_t targ_entry, gfp_t gfp,
> unsigned int order, struct vm_fault *vmf,
> - struct mempolicy *mpol, pgoff_t ilx)
> + struct mempolicy *mpol, pgoff_t ilx,
> + bool skip_lru)
> {
> int err;
> swp_entry_t entry;
> @@ -484,7 +485,8 @@ static struct folio *__swap_cache_alloc(struct swap_cluster_info *ci,
> lruvec_stat_mod_folio(folio, NR_SWAPCACHE, nr_pages);
>
> /* Caller will initiate read into locked new_folio */
> - folio_add_lru(folio);
> + if (!skip_lru)
> + folio_add_lru(folio);
> return folio;
> }
>
> @@ -507,7 +509,8 @@ static struct folio *__swap_cache_alloc(struct swap_cluster_info *ci,
> */
> struct folio *swap_cache_alloc_folio(swp_entry_t targ_entry, gfp_t gfp,
> unsigned long orders, struct vm_fault *vmf,
> - struct mempolicy *mpol, pgoff_t ilx)
> + struct mempolicy *mpol, pgoff_t ilx,
> + bool skip_lru)
Compared to the bool skip_lru here, will this work better? (not tested)
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 8afd0b2d7c27..7ff5254b6ff8 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -487,9 +487,6 @@ static struct folio *__swap_cache_alloc(struct swap_cluster_info *ci,
node_stat_mod_folio(folio, NR_FILE_PAGES, nr_pages);
lruvec_stat_mod_folio(folio, NR_SWAPCACHE, nr_pages);
-
- /* Caller will initiate read into locked new_folio */
- folio_add_lru(folio);
return folio;
}
@@ -651,6 +648,8 @@ static struct folio *swap_cache_read_folio(swp_entry_t entry, gfp_t gfp,
if (folio)
return folio;
folio = swap_cache_alloc_folio(entry, gfp, orders, NULL, mpol, ilx);
+ if (!IS_ERR(folio))
+ folio_add_lru(folio);
} while (PTR_ERR(folio) == -EEXIST);
if (IS_ERR_OR_NULL(folio))
@@ -692,6 +691,8 @@ struct folio *swapin_sync(swp_entry_t entry, gfp_t gfp,
if (folio)
return folio;
folio = swap_cache_alloc_folio(entry, gfp, orders, vmf, mpol, ilx);
+ if (!IS_ERR(folio))
+ folio_add_lru(folio);
} while (PTR_ERR(folio) == -EEXIST);
It's identical code wise, just fewer arguments and changes.
Prehaps also rename swap_cache_alloc_folio to __swap_cache_alloc_folio
and update kdoc that caller need to ensure the folio won't be leaked off-LRU
and unreclaimable now.
next prev parent reply other threads:[~2026-07-18 11:10 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-18 9:36 [PATCH 0/2] mm: zswap: free cold writeback folios promptly Alexandre Ghiti
2026-07-18 9:36 ` [PATCH 1/2] mm: zswap: free synchronous-IO writeback folios directly Alexandre Ghiti
2026-07-18 11:10 ` Kairui Song [this message]
2026-07-18 9:36 ` [PATCH 2/2] mm: zswap: deferred dropbehind free of writeback folios 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=altSA1zXhzvHPJYe@KASONG-MC4 \
--to=ryncsn@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=baohua@kernel.org \
--cc=baoquan.he@linux.dev \
--cc=chengming.zhou@linux.dev \
--cc=chrisl@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=jack@suse.cz \
--cc=kasong@tencent.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nphamcs@gmail.com \
--cc=shikemeng@huaweicloud.com \
--cc=willy@infradead.org \
--cc=yosry@kernel.org \
--cc=youngjun.park@lge.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.