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 11/19] mm, swap: add CONFIG_XSWAP_DEFAULT_MAX
Date: Mon, 9 Nov 2026 13:54:47 +0800 [thread overview]
Message-ID: <20261109055455.536925-12-baoquan.he@linux.dev> (raw)
In-Reply-To: <20261109055455.536925-1-baoquan.he@linux.dev>
From: Baoquan He <hebaoquan@kylinos.cn>
Add a build-time default for the size of a new xswap device. The value
can be a percentage of RAM, a size in bytes, or "max". "max" means the
largest size the device can address. xswap.max= on the command line
overrides this default.
The build-time default is clamped to the device limit. An explicit
xswap.max= that is too large is refused.
If the build-time default cannot be parsed, or is a byte size below one
cluster, use 200% instead. A percentage default can still be below one
cluster after RAM is known. In that case, device creation fails.
Document the sysfs ABI, the stable id, and the synthetic /proc/swaps
name. Also document that zswap must stay enabled while xswap devices
exist.
Signed-off-by: Baoquan He <hebaoquan@kylinos.cn>
---
.../ABI/testing/sysfs-kernel-mm-xswap | 38 +++++++++++++++++++
.../admin-guide/kernel-parameters.txt | 3 +-
Documentation/admin-guide/mm/zswap.rst | 9 +++++
MAINTAINERS | 1 +
mm/Kconfig | 11 ++++++
mm/swapfile.c | 22 +++++++++--
6 files changed, 79 insertions(+), 5 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-kernel-mm-xswap
diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-xswap b/Documentation/ABI/testing/sysfs-kernel-mm-xswap
new file mode 100644
index 000000000000..38eead0b1b31
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-kernel-mm-xswap
@@ -0,0 +1,38 @@
+What: /sys/kernel/mm/xswap/
+Date: October 2026
+Contact: Linux memory management mailing list <linux-mm@kvack.org>
+Description: File-less swap devices backed by zswap.
+
+ An xswap device has no backing file. Its slots are backed
+ by the zswap pool, and the device size is set at boot with
+ xswap.max= or CONFIG_XSWAP_DEFAULT_MAX. The size is fixed
+ for the lifetime of the device.
+
+ The name shown in /proc/swaps, xswap<id>, is synthetic and
+ is not a path. It cannot be passed to swapoff(2), so
+ swapoff -a reports an error for these entries. Use the
+ destroy attribute instead.
+
+ An xswap device requires zswap. Disabling zswap at runtime
+ (enabled=0, or max_pool_percent=0) while xswap devices
+ exist leaves them without backing: existing entries can
+ still be read, but new pages cannot be stored. Destroy the
+ xswap devices before disabling zswap.
+
+What: /sys/kernel/mm/xswap/create
+Date: October 2026
+Contact: Linux memory management mailing list <linux-mm@kvack.org>
+Description: Create an xswap device.
+
+ Write an optional priority (0..32767), or write nothing for
+ the default priority. The write fails if zswap is disabled
+ or if the configured size is smaller than one cluster.
+
+What: /sys/kernel/mm/xswap/destroy
+Date: October 2026
+Contact: Linux memory management mailing list <linux-mm@kvack.org>
+Description: Destroy an xswap device.
+
+ Write the device's stable id. The id is the number after
+ "xswap" in /proc/swaps, for example 1 for xswap1. It is
+ not a swap type and is never reused.
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index e92a1b9062a6..6e2d2747a26f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -8743,5 +8743,6 @@ Kernel parameters
Maximum size of a new xswap device. The value is a
size in bytes with an optional KMGTPE suffix, a
percentage of RAM, or "max" for the largest size
- the device can address.
+ the device can address. The default is set by
+ CONFIG_XSWAP_DEFAULT_MAX.
Format: <size>[KMGTPE] | <percent>% | max
diff --git a/Documentation/admin-guide/mm/zswap.rst b/Documentation/admin-guide/mm/zswap.rst
index 2464425c783d..886b50ca90b1 100644
--- a/Documentation/admin-guide/mm/zswap.rst
+++ b/Documentation/admin-guide/mm/zswap.rst
@@ -136,3 +136,12 @@ selected.
A debugfs interface is provided for various statistic about pool size, number
of pages stored, same-value filled pages and various counters for the reasons
pages are rejected.
+
+xswap devices
+-------------
+
+An xswap device is a file-less swap device backed by zswap. While such a
+device exists, do not disable zswap at runtime (``enabled=0``) or set
+``max_pool_percent`` to 0. The device would have no backing: pages already
+in zswap can still be read, but new pages cannot be stored. Destroy the
+xswap devices first.
diff --git a/MAINTAINERS b/MAINTAINERS
index 0cf24eee20bb..66078761b746 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17910,6 +17910,7 @@ R: Youngjun Park <youngjun.park@lge.com>
L: linux-mm@kvack.org
S: Maintained
F: Documentation/ABI/testing/sysfs-kernel-mm-swap
+F: Documentation/ABI/testing/sysfs-kernel-mm-xswap
F: Documentation/mm/swap-table.rst
F: include/linux/swap.h
F: include/linux/swap_ops.h
diff --git a/mm/Kconfig b/mm/Kconfig
index 9bdb905a66ef..902e3b1a6e35 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -131,6 +131,17 @@ config XSWAP
array is backed by a sparse vmalloc area that is mapped lazily
in chunks, avoiding static pre-allocation overhead.
+config XSWAP_DEFAULT_MAX
+ string "Default maximum size of a new xswap device"
+ depends on XSWAP
+ default "200%"
+ help
+ The maximum size of a newly created xswap device. It accepts a
+ percentage of RAM (for example "200%"), a size (for example "2T"),
+ or "max" for the largest size the device can address.
+
+ xswap.max= on the kernel command line overrides this value.
+
config ZSMALLOC
tristate
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 498fbf6df1cd..cb53f9415de8 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -161,9 +161,12 @@ static bool xswap_size_max;
static bool xswap_size_set; /* xswap.max= was given */
/*
- * Parse "200%", "2T" or "max". @str is not modified.
+ * Parse "200%", "2T" or "max". @str is not modified. @cmdline tells an
+ * explicit xswap.max= from the build-time default, which is clamped
+ * instead of refused when it is too large.
*/
-static int __init xswap_parse_size(const char *str, const char *what)
+static int __init xswap_parse_size(const char *str, const char *what,
+ bool cmdline)
{
const char *pct;
char buf[16];
@@ -192,12 +195,16 @@ static int __init xswap_parse_size(const char *str, const char *what)
bytes = memparse(str, &end);
if (*end || bytes < PAGE_SIZE)
goto bad;
+ /* A default below one cluster would fail every create. */
+ if (!cmdline && bytes < (unsigned long)SWAPFILE_CLUSTER * PAGE_SIZE)
+ goto bad;
xswap_size_bytes = bytes;
xswap_size_pct = 0;
xswap_size_max = false;
}
- xswap_size_set = true;
+ if (cmdline)
+ xswap_size_set = true;
return 0;
bad:
pr_err("xswap: bad %s=%s\n", what, str);
@@ -206,7 +213,7 @@ static int __init xswap_parse_size(const char *str, const char *what)
static int __init xswap_max_setup(char *str)
{
- xswap_parse_size(str, "xswap.max");
+ xswap_parse_size(str, "xswap.max", true);
return 1;
}
__setup("xswap.max=", xswap_max_setup);
@@ -4830,6 +4837,13 @@ static int __init swapfile_init(void)
{
swapfile_maximum_size = arch_max_swapfile_size();
+#ifdef CONFIG_XSWAP
+ /* xswap.max= on the command line overrides the build-time default. */
+ if (!xswap_size_set)
+ xswap_parse_size(CONFIG_XSWAP_DEFAULT_MAX,
+ "CONFIG_XSWAP_DEFAULT_MAX", false);
+#endif
+
/*
* Once a cluster is freed, it's swap table content is read
* only, and all swap cache readers (swap_cache_*) verifies
--
2.54.0
next prev parent reply other threads:[~2026-11-09 5:56 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 ` Baoquan He [this message]
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 ` [PATCH v5 16/19] mm, swap: prepare xswap_unmap_clusters for range shrinking Baoquan He
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-12-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.