include/linux/plist.h | 2 - include/linux/swap.h | 43 +- lib/plist.c | 64 -- mm/swap.h | 12 +- mm/swapfile.c | 1301 +++++++++++++++++++++++++---------------- 5 files changed, 817 insertions(+), 605 deletions(-)
Hi all,
RESEND: Only the first cover letter was sent, with an outdated sender
display name. No patches from the series were sent. This resend uses
the corrected sender identity and starts the complete thread. There are
no code or content changes from the previously reviewed v2 draft.
This is v2 of Kairui's swap priority queue RFC [1]. With Kairui's
agreement, I am carrying this revision while preserving the original
authorship of his patches and Youngjun's per-device percpu-cluster patch.
My substantive code changes are concentrated in patches 3, 9 and 11.
Patches 5, 10 and 12 contain the dependent adaptations needed to keep
the stack coherent and bisectable. The code patch-ids of patches 1, 2,
4, 6, 7, 8 and 13 are unchanged from v1. My Signed-off-by on the full
series records the handoff and DCO chain; Co-developed-by is limited to
the three patches with substantive changes.
The current swap allocator rotates swap_avail_head with plist_requeue()
when it moves between devices of the same priority. That couples device
selection to the global cluster cache and serializes cluster transitions
on swap_avail_lock.
This series first restores per-device percpu clusters, then replaces the
allocation-time plist rotation with a priority-ordered queue. Each
priority has a mostly immutable ring of devices. Per-CPU readers rotate
within a ring after a fixed allocation quota, so the allocator preserves
strict priority ordering without contending on one global rotation point.
The queue is also intended to separate device selection policy from the
per-device cluster allocator. Youngjun's swap-tier series [2] remains
under separate review. This RFC does not introduce a tier ABI or assume
that the tier series has landed: a ring is keyed by the existing swap
priority. If tiers land first, the same queue can become an in-tier
allocation policy rather than a competing tier definition.
Changes since v1
================
The core allocator and lifetime changes are:
- keep a task-local cursor stable across retries, so a retry walk visits
each same-priority peer exactly once even if another task rotates the
shared per-CPU reader;
- disable task migration across the queue walk, keeping queue accounting
and per-CPU cluster allocation on the same CPU while leaving the loop
sleepable;
- retry every same-priority peer for a large folio before returning
-E2BIG, without falling through to a lower priority merely because one
device is fragmented;
- initialize the per-CPU quota consistently;
- represent full/disabled devices with tagged ring entries, serialize tag
writers, and use READ_ONCE()/WRITE_ONCE() for lockless readers;
- publish swap_file, the live percpu reference, queue membership and
SWP_WRITEOK in one swapon writer section, and tighten swapoff disable
and teardown ordering;
- fix the transitional available-list locking and publication issues
reported by Jihan;
- bound allocation-path synchronous discard to one cluster, while the
background worker can continue draining the list; and
- remove the transitional available/active plists and the now-unused
plist_requeue() API after the queue becomes authoritative.
These changes address the public review on patch 9 from Youngjun and
Jihan [3][4].
Open questions
==============
Two performance-policy questions from the v1 discussion remain open:
- A one-device ring, which is likely the most common configuration,
still follows the common reader path and takes the local lock. A
size-one fast path could return ring->dev[0] directly while
swapon_rwsem keeps the ring stable. This revision keeps the tested
common path unchanged; feedback on whether the special case is worth
adding would be welcome.
- Full devices remain as masked entries in the static ring. Readers skip
them rather than rebuilding the ring on each full/available transition.
This keeps writers simple, but a workload with many full devices in a
higher-priority ring still pays the masked-entry checks before falling
through. It is not clear that extra per-ring availability state would
justify its synchronization complexity.
Testing
=======
Kunwu ran an A/B/C/D/E matrix on a Kunpeng 920 server with 256 CPUs,
249 GiB RAM and an aarch64 kernel. The workload built a fixed kernel
source with "make -j96 defconfig Image modules" under 2 GiB and 3 GiB
memory cgroups, using eight equal-priority ZRAM devices. Every arm used
one warm-up followed by 12 measured runs.
A/B/C share the v1 base and reproduce the progression reported in v1:
A: before the series
B: after patch 8, with per-device percpu clusters but the old plist
C: after patch 13, with the complete priority queue
D/E share the tested v2 base and isolate the current series:
D: before the series
E: after all 13 v2 patches
1. Reproducing the v1 performance shape
Average system time over 12 measured kernel builds:
2 GiB 3 GiB
Before (A) 40899.14s 22621.86s
After patch 8 (B) 88712.52s 53244.70s
After patch 13 (C) 41140.76s 22925.48s
Patch 8 alone increased system time by 116.9% in the 2 GiB workload
and 135.4% in the 3 GiB workload. Adding the priority queue returned
system time to within 0.59% and 1.34% of A, respectively. The absolute
times differ from the v1 machine, but the expected performance shape is
reproduced: moving the cluster cache back to device scope is expensive
while allocation still rotates the plist, and the queue removes that
contention.
2. Isolating the v2 delta
Average system time over 12 measured runs:
2 GiB 3 GiB
Base (D) 39643.77s 22139.66s
Full v2 (E) 40336.91s 22984.62s
Delta +1.75% +3.82%
Average elapsed time, with sample standard deviation:
2 GiB 3 GiB
Base (D) 518.97 +/- 5.87s 334.07 +/- 4.01s
Full v2 (E) 527.24 +/- 5.21s 342.98 +/- 2.78s
Delta +1.59% +2.67%
The arms were run sequentially rather than interleaved, so these small
D/E deltas may include temporal drift. They are reported as observed
instead of being described as zero regression.
3. Correctness and stress
All 120 measured builds completed with build_exit=0, oom_kill=0,
pswpout>0 and a clean dmesg delta. Arm E also passed tests covering:
- same-priority distribution and lower-priority isolation;
- concurrent swapon/swapoff and /proc/swaps readers;
- full-device mask, unmask and peer refill;
- same-ring large-folio peer retry without fallback; and
- dmesg cleanliness and complete cleanup.
A 600-second stress run concurrently migrated the memory-pressure tasks
across CPUs and inserted and removed a device from the priority ring. It
completed with live workers, swapout progress and a clean dmesg delta.
For the 48 D/E measured runs, all eight ZRAM devices had nonzero recorded
peak usage. On E, the per-sample largest/smallest peak ratio averaged
1.021 for 2 GiB and 1.031 for 3 GiB; the worst observed ratio was 1.049.
4. Scope and posting base
The full server matrix was run from commit 94f9b3980dd4
("mm/page_reporting: Add page_reporting_delay_ms module parameter") to
commit d5c8964cf19f ("lib/plist.c: remove requeue function"). The series
below is rebased onto current mm-unstable; range-diff shows all 13 patches
are patch-identical.
The original 48 GiB BRD workload and a real multi-SSD workload were not
rerun, so this revision makes no BRD or hardware-scaling claim.
Link: https://lore.kernel.org/20260714-swap-pcp-priq-v1-0-de9b164ed419@tencent.com [1]
Link: https://lore.kernel.org/20260713025644.170839-1-youngjun.park@lge.com [2]
Link: https://lore.kernel.org/alZ7UBXweuuOX4qz@yjaykim-PowerEdge-T330 [3]
Link: https://lore.kernel.org/77d6da3d-10af-49a1-a356-72aa8b462e85@gmail.com [4]
Thanks to Kairui for the original design and handoff, Youngjun and Jihan
for the v1 review, and Kunwu for the server validation.
Signed-off-by: Lian Wang (ProcessMission) <lianux.mm@gmail.com>
---
Kairui Song (12):
mm/swap: remove unused parameter for reading swap header
mm/swap: slightly cleanup the code for hibernation error handling
mm/swap: cleanup and document swap device availability flag usage
mm/swap: introduce swap device iteration helper
mm/swap: change the swapon lock into a percpu rwsem
mm/swap: remove swapon mutex and update proc reader
mm/swap: consolidate swap inuse accounting helpers
mm/swap: add priority queue for swap device allocation
mm/swap: remove available list
mm/swap: bound synchronous discard during allocation
mm/swap: drop swap active plist
lib/plist.c: remove requeue function
Youngjun Park (1):
mm/swap: change back to use each swap device's percpu cluster
include/linux/plist.h | 2 -
include/linux/swap.h | 43 +-
lib/plist.c | 64 --
mm/swap.h | 12 +-
mm/swapfile.c | 1301 +++++++++++++++++++++++++----------------
5 files changed, 817 insertions(+), 605 deletions(-)
base-commit: aeddb4d52acfcc5ce5e988acd48f2906fe966ca3
--
2.55.0
On Sat, 29 Aug 2026 15:43:50 +0800 "Lian Wang (ProcessMission)" <lianux.mm@gmail.com> wrote:
> Hi all,
>
> RESEND: Only the first cover letter was sent, with an outdated sender
> display name. No patches from the series were sent. This resend uses
> the corrected sender identity and starts the complete thread. There are
> no code or content changes from the previously reviewed v2 draft.
>
> This is v2 of Kairui's swap priority queue RFC [1]. With Kairui's
> agreement, I am carrying this revision while preserving the original
> authorship of his patches and Youngjun's per-device percpu-cluster patch.
>
> My substantive code changes are concentrated in patches 3, 9 and 11.
> Patches 5, 10 and 12 contain the dependent adaptations needed to keep
> the stack coherent and bisectable. The code patch-ids of patches 1, 2,
> 4, 6, 7, 8 and 13 are unchanged from v1. My Signed-off-by on the full
> series records the handoff and DCO chain; Co-developed-by is limited to
> the three patches with substantive changes.
>
> The current swap allocator rotates swap_avail_head with plist_requeue()
> when it moves between devices of the same priority. That couples device
> selection to the global cluster cache and serializes cluster transitions
> on swap_avail_lock.
>
> This series first restores per-device percpu clusters, then replaces the
> allocation-time plist rotation with a priority-ordered queue. Each
> priority has a mostly immutable ring of devices. Per-CPU readers rotate
> within a ring after a fixed allocation quota, so the allocator preserves
> strict priority ordering without contending on one global rotation point.
>
> The queue is also intended to separate device selection policy from the
> per-device cluster allocator. Youngjun's swap-tier series [2] remains
> under separate review. This RFC does not introduce a tier ABI or assume
> that the tier series has landed: a ring is keyed by the existing swap
> priority. If tiers land first, the same queue can become an in-tier
> allocation policy rather than a competing tier definition.
>
I've completed the functional, stress, and A/B/C/D/E performance testing
on my side.
The results are consistent with the expected v1 performance shape, and
I don't see a significant performance regression for the full v2 series
in this workload.
I'm also reviewing the v2 code, particularly the allocation queue,
locking, and swapoff/lifetime changes. I'll follow up on the thread with
any findings.
Tested-by: Kunwu Chan <kunwu.chan@gmail.com>
Best,
Kunwu
> Changes since v1
> ================
>
> The core allocator and lifetime changes are:
>
> - keep a task-local cursor stable across retries, so a retry walk visits
> each same-priority peer exactly once even if another task rotates the
> shared per-CPU reader;
> - disable task migration across the queue walk, keeping queue accounting
> and per-CPU cluster allocation on the same CPU while leaving the loop
> sleepable;
> - retry every same-priority peer for a large folio before returning
> -E2BIG, without falling through to a lower priority merely because one
> device is fragmented;
> - initialize the per-CPU quota consistently;
> - represent full/disabled devices with tagged ring entries, serialize tag
> writers, and use READ_ONCE()/WRITE_ONCE() for lockless readers;
> - publish swap_file, the live percpu reference, queue membership and
> SWP_WRITEOK in one swapon writer section, and tighten swapoff disable
> and teardown ordering;
> - fix the transitional available-list locking and publication issues
> reported by Jihan;
> - bound allocation-path synchronous discard to one cluster, while the
> background worker can continue draining the list; and
> - remove the transitional available/active plists and the now-unused
> plist_requeue() API after the queue becomes authoritative.
>
> These changes address the public review on patch 9 from Youngjun and
> Jihan [3][4].
>
> Open questions
> ==============
>
> Two performance-policy questions from the v1 discussion remain open:
>
> - A one-device ring, which is likely the most common configuration,
> still follows the common reader path and takes the local lock. A
> size-one fast path could return ring->dev[0] directly while
> swapon_rwsem keeps the ring stable. This revision keeps the tested
> common path unchanged; feedback on whether the special case is worth
> adding would be welcome.
> - Full devices remain as masked entries in the static ring. Readers skip
> them rather than rebuilding the ring on each full/available transition.
> This keeps writers simple, but a workload with many full devices in a
> higher-priority ring still pays the masked-entry checks before falling
> through. It is not clear that extra per-ring availability state would
> justify its synchronization complexity.
>
> Testing
> =======
>
> Kunwu ran an A/B/C/D/E matrix on a Kunpeng 920 server with 256 CPUs,
> 249 GiB RAM and an aarch64 kernel. The workload built a fixed kernel
> source with "make -j96 defconfig Image modules" under 2 GiB and 3 GiB
> memory cgroups, using eight equal-priority ZRAM devices. Every arm used
> one warm-up followed by 12 measured runs.
>
> A/B/C share the v1 base and reproduce the progression reported in v1:
>
> A: before the series
> B: after patch 8, with per-device percpu clusters but the old plist
> C: after patch 13, with the complete priority queue
>
> D/E share the tested v2 base and isolate the current series:
>
> D: before the series
> E: after all 13 v2 patches
>
> 1. Reproducing the v1 performance shape
>
> Average system time over 12 measured kernel builds:
>
> 2 GiB 3 GiB
> Before (A) 40899.14s 22621.86s
> After patch 8 (B) 88712.52s 53244.70s
> After patch 13 (C) 41140.76s 22925.48s
>
> Patch 8 alone increased system time by 116.9% in the 2 GiB workload
> and 135.4% in the 3 GiB workload. Adding the priority queue returned
> system time to within 0.59% and 1.34% of A, respectively. The absolute
> times differ from the v1 machine, but the expected performance shape is
> reproduced: moving the cluster cache back to device scope is expensive
> while allocation still rotates the plist, and the queue removes that
> contention.
>
> 2. Isolating the v2 delta
>
> Average system time over 12 measured runs:
>
> 2 GiB 3 GiB
> Base (D) 39643.77s 22139.66s
> Full v2 (E) 40336.91s 22984.62s
> Delta +1.75% +3.82%
>
> Average elapsed time, with sample standard deviation:
>
> 2 GiB 3 GiB
> Base (D) 518.97 +/- 5.87s 334.07 +/- 4.01s
> Full v2 (E) 527.24 +/- 5.21s 342.98 +/- 2.78s
> Delta +1.59% +2.67%
>
> The arms were run sequentially rather than interleaved, so these small
> D/E deltas may include temporal drift. They are reported as observed
> instead of being described as zero regression.
>
> 3. Correctness and stress
>
> All 120 measured builds completed with build_exit=0, oom_kill=0,
> pswpout>0 and a clean dmesg delta. Arm E also passed tests covering:
>
> - same-priority distribution and lower-priority isolation;
> - concurrent swapon/swapoff and /proc/swaps readers;
> - full-device mask, unmask and peer refill;
> - same-ring large-folio peer retry without fallback; and
> - dmesg cleanliness and complete cleanup.
>
> A 600-second stress run concurrently migrated the memory-pressure tasks
> across CPUs and inserted and removed a device from the priority ring. It
> completed with live workers, swapout progress and a clean dmesg delta.
>
> For the 48 D/E measured runs, all eight ZRAM devices had nonzero recorded
> peak usage. On E, the per-sample largest/smallest peak ratio averaged
> 1.021 for 2 GiB and 1.031 for 3 GiB; the worst observed ratio was 1.049.
>
> 4. Scope and posting base
>
> The full server matrix was run from commit 94f9b3980dd4
> ("mm/page_reporting: Add page_reporting_delay_ms module parameter") to
> commit d5c8964cf19f ("lib/plist.c: remove requeue function"). The series
> below is rebased onto current mm-unstable; range-diff shows all 13 patches
> are patch-identical.
>
> The original 48 GiB BRD workload and a real multi-SSD workload were not
> rerun, so this revision makes no BRD or hardware-scaling claim.
>
> Link: https://lore.kernel.org/20260714-swap-pcp-priq-v1-0-de9b164ed419@tencent.com [1]
> Link: https://lore.kernel.org/20260713025644.170839-1-youngjun.park@lge.com [2]
> Link: https://lore.kernel.org/alZ7UBXweuuOX4qz@yjaykim-PowerEdge-T330 [3]
> Link: https://lore.kernel.org/77d6da3d-10af-49a1-a356-72aa8b462e85@gmail.com [4]
>
> Thanks to Kairui for the original design and handoff, Youngjun and Jihan
> for the v1 review, and Kunwu for the server validation.
>
> Signed-off-by: Lian Wang (ProcessMission) <lianux.mm@gmail.com>
> ---
>
> Kairui Song (12):
> mm/swap: remove unused parameter for reading swap header
> mm/swap: slightly cleanup the code for hibernation error handling
> mm/swap: cleanup and document swap device availability flag usage
> mm/swap: introduce swap device iteration helper
> mm/swap: change the swapon lock into a percpu rwsem
> mm/swap: remove swapon mutex and update proc reader
> mm/swap: consolidate swap inuse accounting helpers
> mm/swap: add priority queue for swap device allocation
> mm/swap: remove available list
> mm/swap: bound synchronous discard during allocation
> mm/swap: drop swap active plist
> lib/plist.c: remove requeue function
>
> Youngjun Park (1):
> mm/swap: change back to use each swap device's percpu cluster
>
> include/linux/plist.h | 2 -
> include/linux/swap.h | 43 +-
> lib/plist.c | 64 --
> mm/swap.h | 12 +-
> mm/swapfile.c | 1301 +++++++++++++++++++++++++----------------
> 5 files changed, 817 insertions(+), 605 deletions(-)
>
>
> base-commit: aeddb4d52acfcc5ce5e988acd48f2906fe966ca3
> --
> 2.55.0
>
Sent using hkml (https://github.com/sjp38/hackermail)
On Sat, Aug 29, 2026 at 03:43:50PM +0800, Lian Wang (ProcessMission) wrote:
> Hi all,
>
> RESEND: Only the first cover letter was sent, with an outdated sender
> display name. No patches from the series were sent. This resend uses
> the corrected sender identity and starts the complete thread. There are
> no code or content changes from the previously reviewed v2 draft.
>
> This is v2 of Kairui's swap priority queue RFC [1]. With Kairui's
> agreement, I am carrying this revision while preserving the original
> authorship of his patches and Youngjun's per-device percpu-cluster patch.
Hi Lian,
Thank you for work!
Since tiers come up further down, I'd like to raise a point about the
patch subject line too. As Kairui mentioned in RFC v1 that we would
stay aligned with tiers, would it make sense to frame this RFC as a
per-tier allocation policy (or something along those lines)? Kairui,
what's your opinion?
Devices assigned to the same tier already share the same priority, so
I don't think the allocation policy needs more than one option for
that case (I can't think of a use case that would need it).
1. For legacy swap with no tier configured, define it as a single
priority treated as one tier.
2. When priorities match, allocation naturally falls to a single
policy (not a queue). the concrete policy here is this
queue-based scheme.
3. When tiers are enabled, devices previously assigned under legacy
swap are reassigned to tiers at runtime.
(This means different swap device on same tier handled like same priority device)
Point 3 reflects my thinking based on the current tier implementation.
Current tier concept is good enough, but I keep thinking how to improve...
(This means I don't think we need runtime tier enablement with
ability to change swap tier number range. swap device on/off & priority change not that dynamic? right?)
There's an alternative tier-assignment approach that might fit this
series better, and I'd like your thoughts on it.
a. Fix the tier as a boot-time parameter.
(This way, legacy swap without tiers never hits case 3 at all. On
kernels with tiers enabled, swap devices are assigned per their
tier, and devices in the same tier follow the same policy even if
their priorities differ. plus ther is no swaptier interface management
add, remove, etc)
b. If boot time isn't preferred, define tiers at compile time by
grouping equal priorities, or by splitting the priority range into
1/n buckets based on the number of tiers.
- The tier interface would then only allow naming (or should this
also be fixed at compile time?)
- grouping equal priorities strategy has some limit like
I think this direction aligns well with this patch and, in some
ways, leads to a cleaner architecture. But, both (a) and (b)
have rough edges once I try to work them through in practice, and
each would need to be resolved one at a time with agreement before
introducing it. I'd like to hear other opinions, and if this
is acceptable, I'll introduce original and this idea.
> My substantive code changes are concentrated in patches 3, 9 and 11.
> Patches 5, 10 and 12 contain the dependent adaptations needed to keep
> the stack coherent and bisectable. The code patch-ids of patches 1, 2,
> 4, 6, 7, 8 and 13 are unchanged from v1. My Signed-off-by on the full
> series records the handoff and DCO chain; Co-developed-by is limited to
> the three patches with substantive changes.
>
> The current swap allocator rotates swap_avail_head with plist_requeue()
> when it moves between devices of the same priority. That couples device
> selection to the global cluster cache and serializes cluster transitions
> on swap_avail_lock.
> This series first restores per-device percpu clusters, then replaces the
> allocation-time plist rotation with a priority-ordered queue. Each
> priority has a mostly immutable ring of devices. Per-CPU readers rotate
I think this feature will also be needed on the virtualized swap side,
which makes me wonder whether this patch should go back into the swap
tier series instead. Kairui, Lian, what do you think? (Or separately?)
I've also been thinking about how to move the tier series forward
since v10. I'll prepare v11 shortly.
> within a ring after a fixed allocation quota, so the allocator preserves
> strict priority ordering without contending on one global rotation point.
>
> The queue is also intended to separate device selection policy from the
> per-device cluster allocator. Youngjun's swap-tier series [2] remains
FYI, the thing I've been hesitating over since v10 is that there was
feedback that going through the memcg interface needs more swap code matureness (backend transfer)
and discussion,
so I needed to settle on a direction first.
This patch itself looks like it could align well with the swap-tier
use case (see my note on the interface below). As mentioned above,
I'll follow up with the tier series soon.
> under separate review. This RFC does not introduce a tier ABI or assume
> that the tier series has landed: a ring is keyed by the existing swap
> priority. If tiers land first, the same queue can become an in-tier
> allocation policy rather than a competing tier definition.
This is the direction I was hoping for. (TBD)
Within a tier. /sys/kernel/mm/swap/tiers/<tier name>/<policy name>
- Across tiers: allocation follows priority based on speed
differences.
- Within a tier: a selectable policy applies.
- The default policy is this series' scheme.
- Priority-based distribution should also be possible within a
tier.
- If xswap is introduced, its allocation should be selectable based
on memcg.
- Other custom allocation methods (round-robin, etc.).
...
> Testing
> =======
>
> Kunwu ran an A/B/C/D/E matrix on a Kunpeng 920 server with 256 CPUs,
> 249 GiB RAM and an aarch64 kernel. The workload built a fixed kernel
> source with "make -j96 defconfig Image modules" under 2 GiB and 3 GiB
> memory cgroups, using eight equal-priority ZRAM devices. Every arm used
> one warm-up followed by 12 measured runs.
>
> A/B/C share the v1 base and reproduce the progression reported in v1:
>
> A: before the series
> B: after patch 8, with per-device percpu clusters but the old plist
> C: after patch 13, with the complete priority queue
>
> D/E share the tested v2 base and isolate the current series:
>
> D: before the series
> E: after all 13 v2 patches
>
> 1. Reproducing the v1 performance shape
>
> Average system time over 12 measured kernel builds:
>
> 2 GiB 3 GiB
> Before (A) 40899.14s 22621.86s
> After patch 8 (B) 88712.52s 53244.70s
> After patch 13 (C) 41140.76s 22925.48s
>
> Patch 8 alone increased system time by 116.9% in the 2 GiB workload
> and 135.4% in the 3 GiB workload. Adding the priority queue returned
> system time to within 0.59% and 1.34% of A, respectively. The absolute
> times differ from the v1 machine, but the expected performance shape is
> reproduced: moving the cluster cache back to device scope is expensive
> while allocation still rotates the plist, and the queue removes that
> contention.
>
> 2. Isolating the v2 delta
>
> Average system time over 12 measured runs:
>
> 2 GiB 3 GiB
> Base (D) 39643.77s 22139.66s
> Full v2 (E) 40336.91s 22984.62s
> Delta +1.75% +3.82%
>
> Average elapsed time, with sample standard deviation:
>
> 2 GiB 3 GiB
> Base (D) 518.97 +/- 5.87s 334.07 +/- 4.01s
> Full v2 (E) 527.24 +/- 5.21s 342.98 +/- 2.78s
> Delta +1.59% +2.67%
>
> The arms were run sequentially rather than interleaved, so these small
> D/E deltas may include temporal drift. They are reported as observed
> instead of being described as zero regression.
No regression is great news. the plist refactor is valuable on its
own merits.
That said, could you also share data on other angles, such as lock-
contention benefits, or advantages in other use-case scenarios? (I'll
also think about what would be worth testing here.)
I've done an initial pass and given my review. I'll keep providing
feedback as I go through the patch contents. :)
Youngjun
On Fri, 4 Sep 2026 16:13:10 +0900 Youngjun Park <youngjun.park@lge.com> wrote: > Since tiers come up further down, I'd like to raise a point about the > patch subject line too. As Kairui mentioned in RFC v1 that we would > stay aligned with tiers, would it make sense to frame this RFC as a > per-tier allocation policy (or something along those lines)? Kairui, > what's your opinion? Thanks for the thoughtful feedback and for taking an initial pass over the series. I agree that this queue could naturally become an in-tier allocation policy. For this RFC, I would prefer to keep it separate and scoped to the existing priority semantics while the tier and virtual-swap directions are still being settled. We can revisit the subject and naming once that boundary is clearer. I will also sync with Kairui when he has time. He has several things in flight, but his view on the ownership and framing would be valuable. > Devices assigned to the same tier already share the same priority, so > I don't think the allocation policy needs more than one option for > that case (I can't think of a use case that would need it). > > 1. For legacy swap with no tier configured, define it as a single > priority treated as one tier. > 2. When priorities match, allocation naturally falls to a single > policy (not a queue). the concrete policy here is this > queue-based scheme. > 3. When tiers are enabled, devices previously assigned under legacy > swap are reassigned to tiers at runtime. > (This means different swap device on same tier handled like same priority device) These are useful design points. I would like to study the concrete v11 before deciding between runtime, boot-time, or compile-time tier assignment. It seems safer not to bind this queue RFC to a permanent tier interface while those semantics and the virtual-swap backend model are still under discussion. > I think this feature will also be needed on the virtualized swap side, > which makes me wonder whether this patch should go back into the swap > tier series instead. Kairui, Lian, what do you think? (Or separately?) > > I've also been thinking about how to move the tier series forward > since v10. I'll prepare v11 shortly. I agree that the mechanism should be useful on the virtualized-swap side too. Once you post v11, I will study and review it, and I am happy to work with you on whether the queue should be rebased onto the tier infrastructure or remain a separate policy layer. > This is the direction I was hoping for. (TBD) > > Within a tier. /sys/kernel/mm/swap/tiers/<tier name>/<policy name> > > - Across tiers: allocation follows priority based on speed > differences. > - Within a tier: a selectable policy applies. > - The default policy is this series' scheme. > - Priority-based distribution should also be possible within a > tier. > - If xswap is introduced, its allocation should be selectable based > on memcg. > - Other custom allocation methods (round-robin, etc.). The split between cross-tier selection and an in-tier allocation policy makes sense to me. Keeping the current queue as an independent mechanism for now should let us evaluate it as the possible default policy without committing the tier ABI prematurely. > No regression is great news. the plist refactor is valuable on its > own merits. > > That said, could you also share data on other angles, such as lock- > contention benefits, or advantages in other use-case scenarios? (I'll > also think about what would be worth testing here.) Yes. I will add direct lock-contention measurements, the one-device case, and higher-priority rings containing full devices. Let's keep sharing results and test ideas as the two series evolve. > I've done an initial pass and given my review. I'll keep providing > feedback as I go through the patch contents. :) Thank you. The v2 code delta from v1 is intentionally focused. If you find any problem in the individual patches, please let me know and I will iterate on it with you. I also plan to spend time this weekend studying your recent v3 swap work, and I look forward to reviewing v11. Thanks, Lian
On Fri, Sep 4, 2026 at 6:12 PM Lian Wang (ProcessMission) <lianux.mm@gmail.com> wrote: > > On Fri, 4 Sep 2026 16:13:10 +0900 Youngjun Park <youngjun.park@lge.com> wrote: > > > Since tiers come up further down, I'd like to raise a point about the > > patch subject line too. As Kairui mentioned in RFC v1 that we would > > stay aligned with tiers, would it make sense to frame this RFC as a > > per-tier allocation policy (or something along those lines)? Kairui, > > what's your opinion? > > Thanks for the thoughtful feedback and for taking an initial pass over > the series. > > I agree that this queue could naturally become an in-tier allocation > policy. For this RFC, I would prefer to keep it separate and scoped to > the existing priority semantics while the tier and virtual-swap > directions are still being settled. We can revisit the subject and > naming once that boundary is clearer. Hi All! We can start with adpating the default priority if tiering still needs more time to land, Not changing the user interface means less risk. It's also fine to implement tiering first, there are some other blocking issues for tier though. With tiering I think we will still need rotation of devices in the same priorities / tier. Once tier is ready, we can further extend the rotation in the same tier; that's something to discuss. > > I will also sync with Kairui when he has time. He has several things in > flight, but his view on the ownership and framing would be valuable. > > > Devices assigned to the same tier already share the same priority, so Hmm, the current posted tier is a band of priorities. Do you mean that when tiering is enabled, devices in the same tier, despite of having different priority, will be used equally? And is priority ineffective then? > > I don't think the allocation policy needs more than one option for > > that case (I can't think of a use case that would need it). > > > > 1. For legacy swap with no tier configured, define it as a single > > priority treated as one tier. > > 2. When priorities match, allocation naturally falls to a single > > policy (not a queue). the concrete policy here is this > > queue-based scheme. > > 3. When tiers are enabled, devices previously assigned under legacy > > swap are reassigned to tiers at runtime. > > (This means different swap device on same tier handled like same priority device) > > These are useful design points. I would like to study the concrete v11 > before deciding between runtime, boot-time, or compile-time tier > assignment. It seems safer not to bind this queue RFC to a permanent > tier interface while those semantics and the virtual-swap backend model > are still under discussion. > > > I think this feature will also be needed on the virtualized swap side, > > which makes me wonder whether this patch should go back into the swap > > tier series instead. Kairui, Lian, what do you think? (Or separately?) I'm fine as long as there won't be a regression. I remember V10 of tier didn't touch this yet so the regression is limited to tier enabled case, so no existing case will experience any issue, that is fine. Causing a performance regression for existing usecases is usually a bad idea.
On Fri, Sep 04, 2026 at 09:02:00PM +0800, Kairui Song wrote: > On Fri, Sep 4, 2026 at 6:12 PM Lian Wang (ProcessMission) > <lianux.mm@gmail.com> wrote: > > > > On Fri, 4 Sep 2026 16:13:10 +0900 Youngjun Park <youngjun.park@lge.com> wrote: > > > > > Since tiers come up further down, I'd like to raise a point about the > > > patch subject line too. As Kairui mentioned in RFC v1 that we would > > > stay aligned with tiers, would it make sense to frame this RFC as a > > > per-tier allocation policy (or something along those lines)? Kairui, > > > what's your opinion? > > > > Thanks for the thoughtful feedback and for taking an initial pass over > > the series. > > > > I agree that this queue could naturally become an in-tier allocation > > policy. For this RFC, I would prefer to keep it separate and scoped to > > the existing priority semantics while the tier and virtual-swap > > directions are still being settled. We can revisit the subject and > > naming once that boundary is clearer. > > Hi All! > > We can start with adpating the default priority if tiering still needs > more time to land, Not changing the user interface means less risk. > It's also fine to implement tiering first, there are some other > blocking issues for tier though. > > With tiering I think we will still need rotation of devices in the > same priorities / tier. Once tier is ready, we can further extend the > rotation in the same tier; that's something to discuss. > > > > > I will also sync with Kairui when he has time. He has several things in > > flight, but his view on the ownership and framing would be valuable. > > > > > Devices assigned to the same tier already share the same priority, so > > Hmm, the current posted tier is a band of priorities. Do you mean that > when tiering is enabled, devices in the same tier, despite of having > different priority, will be used equally? And is priority ineffective > then? Hello Kairui Right. My thought is to remove the priority semantics within a tier. Once devices are grouped into the same tier, allocation within that tier should be handled by a tier-specific allocation policy. If users want the traditional priority-based behavior, I think they should assign devices to different tiers and manage them that way. For swap devices assigned to the same tier, we can still leave the behavior flexible through the interfac(they may be treated equally, or priority may still be considered). However, there should be a default allocation policy. > > > I don't think the allocation policy needs more than one option for > > > that case (I can't think of a use case that would need it). > > > > > > 1. For legacy swap with no tier configured, define it as a single > > > priority treated as one tier. > > > 2. When priorities match, allocation naturally falls to a single > > > policy (not a queue). the concrete policy here is this > > > queue-based scheme. > > > 3. When tiers are enabled, devices previously assigned under legacy > > > swap are reassigned to tiers at runtime. > > > (This means different swap device on same tier handled like same priority device) > > > > These are useful design points. I would like to study the concrete v11 > > before deciding between runtime, boot-time, or compile-time tier > > assignment. It seems safer not to bind this queue RFC to a permanent > > tier interface while those semantics and the virtual-swap backend model > > are still under discussion. > > > > > I think this feature will also be needed on the virtualized swap side, > > > which makes me wonder whether this patch should go back into the swap > > > tier series instead. Kairui, Lian, what do you think? (Or separately?) > > I'm fine as long as there won't be a regression. I remember V10 of > tier didn't touch this yet so the regression is limited to tier > enabled case, so no existing case will experience any issue, that is > fine. Causing a performance regression for existing usecases is > usually a bad idea. Yeah right. will consider regession case. Thanks
© 2016 - 2026 Red Hat, Inc.