From: Baoquan He <baoquan.he@linux.dev>
To: linux-mm@kvack.org
Cc: akpm@linux-foundation.org, david@kernel.org, chrisl@kernel.org,
kasong@tencent.com, nphamcs@gmail.com, baohua@kernel.org,
youngjun.park@lge.com, corbet@lwn.net, hannes@cmpxchg.org,
chengming.zhou@linux.dev, kunwu.chan@gmail.com,
klarasmodin@gmail.com, linux-kernel@vger.kernel.org,
Baoquan He <hebaoquan@kylinos.cn>
Subject: [PATCH v5 16/19] mm, swap: prepare xswap_unmap_clusters for range shrinking
Date: Mon, 9 Nov 2026 13:54:52 +0800 [thread overview]
Message-ID: <20261109055455.536925-17-baoquan.he@linux.dev> (raw)
In-Reply-To: <20261109055455.536925-1-baoquan.he@linux.dev>
From: Baoquan He <hebaoquan@kylinos.cn>
Split xswap_unmap_clusters() into a locked helper and a wrapper that
takes xswap_lock. The shrink path already holds xswap_lock and must
call the helper directly.
This is a pure refactor. The existing path already falls back to
bounded batches when the range is too large for vm_area_unmap_pages();
the comments are expanded to explain why, and the cross-reference in
swap_alloc_fast() follows the new name.
Signed-off-by: Baoquan He <hebaoquan@kylinos.cn>
---
mm/swapfile.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/mm/swapfile.c b/mm/swapfile.c
index bc30ab42203c..097ed288b1ca 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1692,7 +1692,7 @@ static bool swap_alloc_fast(struct folio *folio)
*/
unsigned long mapped;
- /* Pairs with the release store in xswap_unmap_clusters(). */
+ /* Pairs with the release store in xswap_unmap_clusters_locked(). */
mapped = smp_load_acquire(&si->nr_clusters_mapped);
if (offset / SWAPFILE_CLUSTER >= mapped) {
@@ -4318,8 +4318,8 @@ static unsigned long xswap_grow(struct swap_info_struct *si)
}
/* Caller must hold si->xswap_lock. Cannot fail. */
-static void xswap_unmap_clusters(struct swap_info_struct *si,
- unsigned long start_idx, unsigned long nr)
+static void xswap_unmap_clusters_locked(struct swap_info_struct *si,
+ unsigned long start_idx, unsigned long nr)
{
unsigned long start_addr = (unsigned long)si->cluster_info +
(size_t)start_idx * sizeof(struct swap_cluster_info);
@@ -4331,8 +4331,6 @@ static void xswap_unmap_clusters(struct swap_info_struct *si,
unsigned int noreclaim_flags;
unsigned long npages, idx;
- mutex_lock(&si->xswap_lock);
-
/*
* Publish the smaller range before its memory goes away. Readers
* that use nr_clusters_mapped without xswap_lock pair with this
@@ -4347,7 +4345,6 @@ static void xswap_unmap_clusters(struct swap_info_struct *si,
* goes away with that cluster; publishing the smaller
* cluster count is still correct.
*/
- mutex_unlock(&si->xswap_lock);
return;
}
@@ -4362,6 +4359,11 @@ static void xswap_unmap_clusters(struct swap_info_struct *si,
npages = (vm_end - vm_start) >> PAGE_SHIFT;
+ /*
+ * vm_area_unmap_pages() refuses a range above totalram_pages() and
+ * returns without clearing the PTEs. Freeing those pages would
+ * leave dangling mappings, so use the batch path for that case.
+ */
if (npages <= totalram_pages()) {
/* Reclaim here would re-enter xswap_map_clusters() and its lock. */
noreclaim_flags = memalloc_noreclaim_save();
@@ -4371,11 +4373,11 @@ static void xswap_unmap_clusters(struct swap_info_struct *si,
if (pages) {
xswap_unmap_range(si, vm_start, vm_end, pages, npages);
kvfree(pages);
- goto out_unlock;
+ return;
}
}
- /* No memory for the array, or too large: unmap in bounded batches. */
+ /* No memory for the array, or too large a range: unmap in batches. */
for (idx = start_idx; idx < start_idx + nr; idx += XSWAP_UNMAP_BATCH_CLUSTERS) {
unsigned long batch = min(start_idx + nr - idx,
XSWAP_UNMAP_BATCH_CLUSTERS);
@@ -4390,7 +4392,13 @@ static void xswap_unmap_clusters(struct swap_info_struct *si,
xswap_unmap_range(si, bstart, bend, batch_pages,
ARRAY_SIZE(batch_pages));
}
-out_unlock:
+}
+
+static void xswap_unmap_clusters(struct swap_info_struct *si,
+ unsigned long start_idx, unsigned long nr)
+{
+ mutex_lock(&si->xswap_lock);
+ xswap_unmap_clusters_locked(si, start_idx, nr);
mutex_unlock(&si->xswap_lock);
}
--
2.54.0
next prev parent reply other threads:[~2026-11-09 5:57 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 5:54 [PATCH v5 00/19] mm, swap: extendable swap devices (xswap phase I) Baoquan He
2026-11-09 5:54 ` [PATCH v5 01/19] mm: xswap support for zswap Baoquan He
2026-11-10 5:57 ` sashiko-bot
2026-11-09 5:54 ` [PATCH v5 02/19] mm, swap: refactor free_swap_cluster_info to take swap_info_struct Baoquan He
2026-11-09 5:54 ` [PATCH v5 03/19] mm, swap: add VM_SPARSE cluster-array helpers for xswap Baoquan He
2026-11-09 5:54 ` [PATCH v5 04/19] mm, swap: use a VM_SPARSE cluster array for xswap devices Baoquan He
2026-11-10 5:58 ` sashiko-bot
2026-11-09 5:54 ` [PATCH v5 05/19] mm, swap: widen swap_info_struct max/pages to unsigned long Baoquan He
2026-11-09 5:54 ` [PATCH v5 06/19] mm, swap: add a sysfs interface to create xswap devices Baoquan He
2026-11-09 5:54 ` [PATCH v5 07/19] mm, swap: refactor swapoff and add xswap_destroy Baoquan He
2026-11-09 5:54 ` [PATCH v5 08/19] mm, swap: require zswap for xswap devices Baoquan He
2026-11-09 5:54 ` [PATCH v5 09/19] mm, swap: use a stable id " Baoquan He
2026-11-10 5:58 ` sashiko-bot
2026-11-09 5:54 ` [PATCH v5 10/19] mm, swap: let the command line set the xswap device size Baoquan He
2026-11-09 5:54 ` [PATCH v5 11/19] mm, swap: add CONFIG_XSWAP_DEFAULT_MAX Baoquan He
2026-11-09 5:54 ` [PATCH v5 12/19] mm, swap: let swapoff destroy xswap devices by name Baoquan He
2026-11-10 5:58 ` sashiko-bot
2026-11-09 5:54 ` [PATCH v5 13/19] mm, swap: add xswap grow trigger on cluster allocation Baoquan He
2026-11-10 5:58 ` sashiko-bot
2026-11-09 5:54 ` [PATCH v5 14/19] mm, swap: add debugfs counters for xswap Baoquan He
2026-11-09 5:54 ` [PATCH v5 15/19] mm, swap: make xswap cluster_info accesses RCU-safe Baoquan He
2026-11-10 5:58 ` sashiko-bot
2026-11-09 5:54 ` Baoquan He [this message]
2026-11-09 5:54 ` [PATCH v5 17/19] mm, swap: add xswap shrink trigger and defer it to a workqueue Baoquan He
2026-11-10 5:58 ` sashiko-bot
2026-11-09 5:54 ` [PATCH v5 18/19] mm, swap: do not give an xswap slot to a cgroup that cannot zswap Baoquan He
2026-11-10 5:58 ` sashiko-bot
2026-11-09 5:54 ` [PATCH v5 19/19] mm, swap: skip the overcommit probe when removing xswap Baoquan He
2026-11-09 6:15 ` [PATCH v5 00/19] mm, swap: extendable swap devices (xswap phase I) Baoquan He
2026-11-12 7:25 ` [syzbot ci] " syzbot ci
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=20261109055455.536925-17-baoquan.he@linux.dev \
--to=baoquan.he@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=chengming.zhou@linux.dev \
--cc=chrisl@kernel.org \
--cc=corbet@lwn.net \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=hebaoquan@kylinos.cn \
--cc=kasong@tencent.com \
--cc=klarasmodin@gmail.com \
--cc=kunwu.chan@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nphamcs@gmail.com \
--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.