All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kunwu Chan <kunwu.chan@gmail.com>
To: Alexandre Ghiti <alex@ghiti.fr>
Cc: Kunwu Chan <kunwu.chan@gmail.com>,
	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>,
	Kairui Song <ryncsn@gmail.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>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>,
	David Hildenbrand <david@kernel.org>,
	Lorenzo Stoakes <ljs@kernel.org>,
	Michal Hocko <mhocko@kernel.org>,
	Axel Rasmussen <axelrasmussen@google.com>,
	Qi Zheng <qi.zheng@linux.dev>,
	Shakeel Butt <shakeel.butt@linux.dev>,
	Wei Xu <weixugc@google.com>, Yuanchu Xie <yuanchu@google.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v4 1/3] mm: swap: move LRU insertion out of the swap cache allocator
Date: Tue,  8 Sep 2026 17:37:00 +0800	[thread overview]
Message-ID: <20260908093711.2364516-1-kunwu.chan@gmail.com> (raw)
In-Reply-To: <20260825135209.3135169-2-alex@ghiti.fr>

On Tue, 25 Aug 2026 15:52:05 +0200 Alexandre Ghiti <alex@ghiti.fr> wrote:

> zswap writeback wants a swap cache folio it can free directly once
> writeback completes, i.e. one that is not on the LRU (folio_add_lru()
> stages the folio in a per-CPU batch that holds a reference until it is
> drained, which keeps remove_mapping() from freeing the folio on
> synchronous devices, and likely on asynchronous ones too).
> 
> So defer the LRU addition to the callers of __swap_cache_alloc_folio(),
> no functional change intended.
> 
> Suggested-by: Kairui Song <kasong@tencent.com>
> Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
> ---
>  mm/swap.h       |  6 +++---
>  mm/swap_state.c | 20 ++++++++++++--------
>  mm/zswap.c      |  5 +++--
>  3 files changed, 18 insertions(+), 13 deletions(-)
> 
> diff --git a/mm/swap.h b/mm/swap.h
> index 77d2d14eda42..fc44daae1de1 100644
> --- a/mm/swap.h
> +++ b/mm/swap.h
> @@ -304,9 +304,9 @@ bool swap_cache_has_folio(swp_entry_t entry);
>  struct folio *swap_cache_get_folio(swp_entry_t entry);
>  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 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);
>  /* 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 727a17ee7821..07418fc94f00 100644
> --- a/mm/swap_state.c
> +++ b/mm/swap_state.c
> @@ -483,13 +483,11 @@ 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;
>  }
>  
>  /**
> - * swap_cache_alloc_folio - Allocate folio for swapped out slot in swap cache.
> + * __swap_cache_alloc_folio - Allocate folio for swapped out slot in swap cache.
>   * @targ_entry: swap entry indicating the target slot
>   * @gfp: memory allocation flags
>   * @orders: allocation orders, must be non zero
> @@ -501,13 +499,17 @@ static struct folio *__swap_cache_alloc(struct swap_cluster_info *ci,
>   * doing IO (e.g. swap in or zswap writeback). The swap slot indicated by
>   * @targ_entry must have a non-zero swap count (swapped out).
>   *
> + * The returned folio is locked and is NOT on the LRU. The caller must either
> + * add it to the LRU with folio_add_lru() so page reclaim can find it, or free
> + * it directly once done; a folio left off the LRU is unreclaimable and leaks.
> + *
>   * Context: Caller must protect the swap device with reference count or locks.
>   * Return: Returns the folio if allocation succeeded and folio is in the swap
>   * cache. Returns error code if failed due to race, OOM or invalid arguments.
>   */
> -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 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)
>  {
>  	int order, err;
>  	struct folio *ret;
> @@ -643,12 +645,13 @@ static struct folio *swap_cache_read_folio(swp_entry_t entry, gfp_t gfp,
>  		folio = swap_cache_get_folio(entry);
>  		if (folio)
>  			return folio;
> -		folio = swap_cache_alloc_folio(entry, gfp, BIT(0), NULL, mpol, ilx);
> +		folio = __swap_cache_alloc_folio(entry, gfp, BIT(0), NULL, mpol, ilx);
>  	} while (PTR_ERR(folio) == -EEXIST);
>  
>  	if (IS_ERR_OR_NULL(folio))
>  		return NULL;
>  
> +	folio_add_lru(folio);
>  	swap_read_folio(folio, plug);
>  	if (readahead) {
>  		folio_set_readahead(folio);
> @@ -683,12 +686,13 @@ struct folio *swapin_sync(swp_entry_t entry, gfp_t gfp, unsigned long orders,
>  		folio = swap_cache_get_folio(entry);
>  		if (folio)
>  			return folio;
> -		folio = swap_cache_alloc_folio(entry, gfp, orders, vmf, mpol, ilx);
> +		folio = __swap_cache_alloc_folio(entry, gfp, orders, vmf, mpol, ilx);
>  	} while (PTR_ERR(folio) == -EEXIST);
>  
>  	if (IS_ERR(folio))
>  		return folio;
>  
> +	folio_add_lru(folio);
>  	swap_read_folio(folio, NULL);
>  	return folio;
>  }
> diff --git a/mm/zswap.c b/mm/zswap.c
> index 761cd699e0a3..8163e6c5f76c 100644
> --- a/mm/zswap.c
> +++ b/mm/zswap.c
> @@ -1000,8 +1000,8 @@ static int zswap_writeback_entry(struct zswap_entry *entry,
>  		return -EEXIST;
>  
>  	mpol = get_task_policy(current);
> -	folio = swap_cache_alloc_folio(swpentry, GFP_KERNEL, BIT(0), NULL, mpol,
> -				       NO_INTERLEAVE_INDEX);
> +	folio = __swap_cache_alloc_folio(swpentry, GFP_KERNEL, BIT(0), NULL, mpol,
> +					 NO_INTERLEAVE_INDEX);
>  	put_swap_device(si);
>  
>  	/*
> @@ -1013,6 +1013,7 @@ static int zswap_writeback_entry(struct zswap_entry *entry,
>  	 */
>  	if (IS_ERR(folio))
>  		return PTR_ERR(folio);
> +	folio_add_lru(folio);
>  
>  	/*
>  	 * folio is locked, and the swapcache is now secured against
> -- 
> 2.53.0-Meta
> 
> 

I checked the callers of __swap_cache_alloc_folio(). The regular 
swap-in paths add the folio to the LRU after allocation, while 
the zswap writeback path keeps it off-LRU for the dropbehind 
handling in patch 3. 
The new allocator contract is preserved by all callers.

swapfile.c still references the old name in a comment — minor 
consistency nit.

Reviewed-by: Kunwu Chan <kunwu.chan@gmail.com>

Thanks,
KunWu



  reply	other threads:[~2026-09-08  9:37 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-25 13:52 [PATCH v4 0/3] mm: zswap: free cold writeback folios promptly Alexandre Ghiti
2026-08-25 13:52 ` [PATCH v4 1/3] mm: swap: move LRU insertion out of the swap cache allocator Alexandre Ghiti
2026-09-08  9:37   ` Kunwu Chan [this message]
2026-09-08 18:26   ` Nhat Pham
2026-08-25 13:52 ` [PATCH v4 2/3] mm: swap: drop dropbehind swap cache folios on writeback completion Alexandre Ghiti
2026-09-08  9:58   ` Kunwu Chan
2026-09-08 18:39   ` Nhat Pham
2026-08-25 13:52 ` [PATCH v4 3/3] mm: zswap: drop cold writeback folios via swap dropbehind Alexandre Ghiti
2026-08-25 15:51   ` Yosry Ahmed
2026-08-25 16:57     ` Alexandre Ghiti
2026-09-08  8:24   ` Kunwu Chan
  -- strict thread matches above, loose matches on Subject: below --
2026-09-11  9:20 [PATCH v4 0/3] mm: fix workingset refaults in the zswap writeback path Alexandre Ghiti
2026-09-11  9:20 ` [PATCH v4 1/3] mm: swap: move LRU insertion out of the swap cache allocator Alexandre Ghiti
2026-09-14  8:02   ` Kairui Song
2026-09-15 10:57     ` 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=20260908093711.2364516-1-kunwu.chan@gmail.com \
    --to=kunwu.chan@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=alex@ghiti.fr \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=baoquan.he@linux.dev \
    --cc=brauner@kernel.org \
    --cc=chengming.zhou@linux.dev \
    --cc=chrisl@kernel.org \
    --cc=david@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=ljs@kernel.org \
    --cc=mhocko@kernel.org \
    --cc=nphamcs@gmail.com \
    --cc=qi.zheng@linux.dev \
    --cc=ryncsn@gmail.com \
    --cc=shakeel.butt@linux.dev \
    --cc=shikemeng@huaweicloud.com \
    --cc=viro@zeniv.linux.org.uk \
    --cc=weixugc@google.com \
    --cc=willy@infradead.org \
    --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.