Re: [RFC PATCH 0/1] mm/swap: keep reclaim batches contiguous on swap

From: Nhat Pham

Date: Thu Oct 22 2026 - 15:58:11 EST


On Thu, Oct 22, 2026 at 8:27 AM Kairui Song <ryncsn@xxxxxxxxx> wrote:
>
> On Thu, Oct 22, 2026 at 11:00 PM Alexandre Ghiti <alex@xxxxxxxx> wrote:
> >
> > 7.3 regressed swap I/O: for the same swap volume, a workload that
> > rewrites swapped out memory sends many more requests to the device.
> > mysql/sysbench in a 256M memcg swapping to an NVMe partition, 7.3
> > compared to the previous version:
> >
> > device read requests per transaction +59%
> > device write requests per transaction +27%
> > throughput, iocost off no change
> > throughput, iocost on -19%
> >
> > Two commits interact:
> >
> > - Commit 9a42aed48421 ("mm, swap: prefer nonfull over free clusters"),
> > in 6.18, makes order-0 allocations fill nonfull clusters before
> > taking a free one.
> >
> > - Commit 3cedb745d354 ("mm: clarify the folio_free_swap() for
> > do_swap_page()"), in 7.3, frees the swap slot on an exclusive write
> > fault. 7.0 to 7.2 kept the slot, but only as a side effect of commit
> > 4b34f1d82c65 ("mm, swap: free the swap cache after folio is
> > mapped").
> >
> > The freed slots leave holes in full clusters, which then go back on
> > the nonfull list. Reclaim allocates slots one folio at a time and
> > merges the writes afterwards, so a batch of LRU-adjacent folios gets
> > scattered over those holes and is written with many small requests.
> > Readahead later finds those pages scattered as well, and needs more
> > read requests to bring them back.
> >
> > I tried three fixes, which perform similarly:
> >
> > A. Revert 3cedb745d354. This keeps the slot on write fault, but undoes
> > the intent of that commit and keeps swap space pinned under dirty
> > pages.
> >
> > B. Below 50% swap usage, make order-0 allocations take a free cluster
> > before a nonfull one. This is what the allocator already does, at
> > any usage, on swap devices with discard enabled (swapon
> > --discard=pages). It is about five lines, but the threshold is
> > arbitrary, it stops working as swap fills up, and it applies to
> > every order-0 allocation, using up the free clusters that
> > nonfull-first keeps for mTHP.
>
> Hi Alexandre,
>
> That's a interesting problem. I think the real problem is with commit
> 9a42aed48421 ("mm, swap: prefer nonfull over free clusters"), right?
>
> It's more like a balance between fragmentation and contiguity of small
> order allocation issue.
>
> Perhaps we should instead always scan the full clusters and revert

You mean scanning the free clusters?

> that one commit? That commit was only following the idea of keeping
> the allocation more compacted for that series, it looked good at that
> time. Since fragmentation issues can be solved in other ways,
> contiguity seems to matter more for large physical swap devices.

Hmm what other way are you thinking of? Physical swap space compaction
requires vswap, which has not landed. And we'd just be kicking the
problem to virtual swap space. Sure, we won't be failing allocation,
but that would still increase the memory overhead, scanning overhead,
etc.

I encountered this myself. Remember when I wrote my own swap allocator
for vswap? In one of the version, I went for free clusters first
instead of partial clusters. It fragmented the swap space, so I had to
copy your homework and went for partially used clusters first...

Anyway, maybe I'm wrong - some numbers would be nice here.