Re: Re: Re: [REGRESSION] mm: MADV_PAGEOUT THP/no-swap refault takes ~1.7x longer on v6.19 than v6.12

"Chengfeng Lin" <[email protected]>
Newsgroups dev.linux.lists.regressions,org.kernel.vger.linux-kernel,org.kvack.linux-mm
Message-ID <7772a33d.10a16.19e4ef701af.Coremail.23020251154299@stu.xmu.edu.cn>
Hi,

I followed up on the MADV_PAGEOUT/no-swap report with local and lab
ftrace/smaps checks.

First, to correct the original report: with no swap configured, this should
not be described as a real pageout/refault workload. A more accurate
description is a MADV_PAGEOUT anon/THP no-swap reclaim-failure path. The
later write-touch is only part of the workload iteration, not evidence that
the pages were actually paged out and faulted back in.

Also, cycle_ns_per_page is wall-clock ns/page for one full workload
iteration. It is not a CPU-cycle counter.

The new lab attribution checks covered:

  - QEMU_SMP=1/2/4 with QEMU_MEM_MB=14336
  - QEMU_SMP=8 with QEMU_MEM_MB=16384
  - QEMU_SMP=16 with QEMU_MEM_MB=32768
  - THP modes: default, hugepage, nohugepage

These are ftrace/smaps attribution runs, not clean timing runs.

The important result is that the default and hugepage cases were not a
same-actual-THP-state comparison between v6.12.77 and v6.19.9:

  - v6.12.77 had AnonHugePages=0 kB
  - v6.19.9 had AnonHugePages=16384 kB
  - v6.19.9 hit split_folio_to_list()
  - v6.12.77 did not hit split_folio_to_list()

In the nohugepage case, both kernels had AnonHugePages=0 kB and neither hit
split_folio_to_list(), but the old-version-faster timing signal was not
stable there.

So I no longer think the original timing table should be treated as a
same-state THP performance regression. The more accurate conclusion is that
the test exposed a no-swap MADV_PAGEOUT anon/THP reclaim split/failure-path
case in v6.19.9, but the compared kernels were not operating on the same
actual THP backing state.

The cleaned-up evidence notes are here:

  https://github.com/lcf0399/linux-mm-regression-evidence-2026-05/tree/0c0e2d9/madvise-pageout-thp-noswap-refault

  https://github.com/lcf0399/linux-mm-regression-evidence-2026-05/tree/0c0e2d9/madvise-pageout-thp-noswap-refault/attribution

If this path is still interesting as an optimization topic, I can keep looking
at whether the no-swap THP split/failure path can fail faster or skip the split.
But I do not want to overstate the original report as a same-state regression.

Thanks,
Chengfeng


> -----Original Message-----
> From: "Chengfeng Lin" <[email protected]>
> Sent:Tuesday, 05/19/2026 15:28:00
> To: "Kairui Song" <[email protected]>
> Cc: "Andrew Morton" <[email protected]>, [email protected], "Liam R. Howlett" <[email protected]>, "David Hildenbrand" <[email protected]>, "Vlastimil Babka" <[email protected]>, "Jann Horn" <[email protected]>, "Johannes Weiner" <[email protected]>, "Michal Hocko" <[email protected]>, "Qi Zheng" <[email protected]>, "Shakeel Butt" <[email protected]>, "Chris Li" <[email protected]>, [email protected], [email protected], [email protected]
> Subject: Re: Re: [REGRESSION] mm: MADV_PAGEOUT THP/no-swap refault takes ~1.7x longer on v6.19 than v6.12
> 
> Hi,
> 
> Thanks for looking at this. Your comments make sense, and sorry for the
> confusing wording in the original report.
> 
> You are right that, with no swap configured, this should not be described
> as a real pageout/refault case. A more accurate description is a
> MADV_PAGEOUT anon/THP no-swap reclaim-failure path. The later write-touch
> is just part of the workload iteration; it should not be presented as
> evidence that the pages were actually paged out and faulted back in.
> 
> Also, cycle_ns_per_page is poorly named. Here "cycle" means one full
> workload iteration, not CPU cycles. The metric is wall-clock nanoseconds
> per page for one complete workload iteration. I will make that clearer in
> future descriptions.
> 
> I agree that the end-to-end timing by itself is not enough to show where
> the time is spent. I will collect a perf or ftrace breakdown comparing
> v6.12.77 and v6.19.9, and follow up with the results on this thread.
> 
> Thanks,
> Chengfeng
> 
> 
> 
> > -----Original Message-----
> > From: "Kairui Song" <[email protected]>
> > Sent:Tuesday, 05/19/2026 02:14:41
> > To: "Chengfeng Lin" <[email protected]>
> > Cc: "Andrew Morton" <[email protected]>, [email protected], "Liam R. Howlett" <[email protected]>, "Lorenzo Stoakes" <[email protected]>, "David Hildenbrand" <[email protected]>, "Vlastimil Babka" <[email protected]>, "Jann Horn" <[email protected]>, "Johannes Weiner" <[email protected]>, "Michal Hocko" <[email protected]>, "Qi Zheng" <[email protected]>, "Shakeel Butt" <[email protected]>, "Chris Li" <[email protected]>, [email protected], [email protected]
> > Subject: Re: [REGRESSION] mm: MADV_PAGEOUT THP/no-swap refault takes ~1.7x longer on v6.19 than v6.12
> > 
> > On Mon, May 18, 2026 at 9:09 PM Chengfeng Lin
> > <[email protected]> wrote:
> > >
> > > Hi,
> > >
> > > I would like to report a userspace-visible performance regression in a
> > > MADV_PAGEOUT workload.
> > 
> > Hi Chengfeng,
> > 
> > Thanks for the report. Very interesting, but it looks a bit confusing.
> > You are doing PAGEOUT of anon pages without swap setup, so nothing is
> > actually being pageouted?
> > 
> > > The workload is intentionally narrow:
> > >
> > >   - map 16 MiB anonymous memory
> > >   - use the default THP policy
> > >   - run in a guest with no configured swap
> > >   - call madvise(MADV_PAGEOUT)
> > >   - refault/write-touch the mapping
> > >
> > > This is not meant as a generic madvise() or generic MADV_PAGEOUT
> > > regression report. The signal is currently scoped to the THP + no-swap +
> > > refault/write-touch workflow above.
> > >
> > > The current public evidence bundle is here:
> > >
> > >   https://github.com/lcf0399/linux-mm-regression-evidence-2026-05/tree/e13469b/madvise-pageout-thp-noswap-refault
> > >
> > > The standalone workload source is here:
> > >
> > >   https://github.com/lcf0399/linux-mm-regression-evidence-2026-05/tree/e13469b/madvise-pageout-thp-noswap-refault/workload
> > >
> > > The formal experiment profile is here:
> > >
> > >   https://github.com/lcf0399/linux-mm-regression-evidence-2026-05/tree/e13469b/madvise-pageout-thp-noswap-refault/experiments
> > >
> > > The formal timing runs compare v6.12.77 and v6.19.9 with similar kernel
> > > configuration, using QEMU direct boot. The formal performance runs were
> > > clean timing runs with coverage disabled. Coverage was collected
> > > separately and is not used for the timing numbers below.
> > >
> > > Lab environment:
> > >
> > >   host label: lcf
> > >   host kernel: Linux 6.14.0-37-generic x86_64
> > >   QEMU: qemu-system-x86_64 8.2.2
> > >   container/cgroup CPU set: 0,2,4,6,8,10,12,14
> > >   container/cgroup memory limit: 16106127360 bytes
> > >   guest memory: QEMU_MEM_MB=14336
> > >   guest CPUs: QEMU_SMP=1/2/4
> > >   repetitions: 9
> > >   version order: interleaved
> > >   performance coverage_enabled: false
> > >
> > > Primary result, cycle_ns_per_page, lower is better:
> > 
> > What is cycle_ns_per_page? The name is ambiguous. "cycle" reads like
> > CPU cycles but the value doesn't match. Or you mean iteration? Can you
> > make this cleaner?
> > 
> > >   CPU   v6.12.77   v6.19.9   old-lower-vs-new   v6.19/v6.12
> > >     1     1900.3    3304.7        42.5%             1.74x
> > >     2     2107.7    3583.2        41.2%             1.70x
> > >     4     2154.2    3690.9        41.6%             1.71x
> > >
> > > MADV_PAGEOUT syscall/reclaim-side segment, advise_ns_per_page, lower is
> > > better:
> > >
> > >   CPU   v6.12.77   v6.19.9   old-lower-vs-new   v6.19/v6.12
> > >     1     1713.2    2922.7        41.4%             1.71x
> > >     2     1924.7    3162.9        39.1%             1.64x
> > >     4     1953.1    3284.2        40.5%             1.68x
> > >
> > > The current mechanism interpretation is that the timing difference is in
> > > the MADV_PAGEOUT/reclaim part, not primarily in the later refault touch.
> > 
> > Right, with no swap configured, the post-advise should not be faulting
> > at all I think? It will just split the pages IIUC, however, that might
> > cause more TLB pressure. But this split-on-alloc-failure path itself
> > wasn't changed from 6.12 to 6.18. If there is no swap, we can skip the
> > split though, and maybe make folio_alloc_swap fail a bit faster.
> > Skipping the split seems more meaningful and could significantly speed
> > up this specific test, if this is necessary.
> > 
> > > The path evidence points at the no-swap reclaim/swap-allocation-failure
> > > chain:
> > >
> > >   madvise(MADV_PAGEOUT)
> > >     -> reclaim_pages()
> > >     -> shrink_folio_list()
> > >     -> folio_alloc_swap()
> > >     -> swap allocation failure path
> > 
> > What you posted, include that repo, seems only has end to end timing.
> > It would be much more
> > useful if you collect a perf or ftrace breakdown something like:
> > https://lore.kernel.org/all/CAMgjq7BfO=dNYep4z1aS7nUAJU3bktR17gYAufx=kkLudq4dAQ@mail.gmail.com/
> > 
> > Or like this:
> > https://lore.kernel.org/all/[email protected]/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.