All of lore.kernel.org
 help / color / mirror / Atom feed
* Improve page refcount scalability
@ 2026-10-13 18:43 Linus Torvalds
  2026-10-13 21:03 ` Matthew Wilcox
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Linus Torvalds @ 2026-10-13 18:43 UTC (permalink / raw)
  To: David Hildenbrand, Kiryl Shutsemau, Ilya Gladyshev,
	Matthew Wilcox, Lorenzo Stoakes, Luis Chamberlain
  Cc: Linux Kernel Mailing List, Linux-MM, Paul E. McKenney

So I've shown this series to people in private and talked about it at
the kernel maintainer summit, so some of you have seen earlier
versions of this already.

This was triggered by several attempts at improving on the scalability
of page ref handling over the last couple of years, particularly for
the common case of normal [p]read() system calls. Willy reported real
users having scalability issues in that area a couple of years ago in
a discussion about buffereed IO scalability limits:

  https://lore.kernel.org/all/Zds8T9O4AYAmdS9d@casper.infradead.org/

and I had a very rough first draft in that discussion:

  https://lore.kernel.org/all/CAHk-=wjOogaW0yLoUqQ0WfQ=etPA4cOFLy56VYCnHVU_DOMLrg@mail.gmail.com/

and it was broken but close enough to working that I kept using it
locally in my own use for a year and a half:

  https://lore.kernel.org/all/CAHk-=wj00-nGmXEkxY=-=Z_qP6kiGUziSFvxHJ9N-cLWry5zpA@mail.gmail.com/

until people pointed out just how broken it was.

Then Kiryl had a slightly fixed-up version of that approach almost
exactly a year ago:

  https://lore.kernel.org/all/20251017141536.577466-1-kirill@shutemov.name/

but that too had problems.

After that, Ilya Gladyshev stepped into the ring with a very different
approach to it, which is now up to version 6:

  https://lore.kernel.org/all/cover.1789239015.git.ilya.gladyshev@linux.dev/

and still has some outstanding known fundamental issues.

So for the kernel maintainer summit this year, where one of the big
topics was going to be LLM use in kernel development, I decided that
hey, I will try to actually *solve* this thing using an LLM to help
with the issues these things have had.

[ I also did another series for a problem with the assoc-array
library. I'll post that separately - that was a lot more pedestrian
"just clean up the code in order to fix a bug" kind of case - not at
all as interesting, but a fallback in case this more interesting
problem were to not pan out. ]

Anyway, the end result is in my kernel tree in the 'rcu-free-v3'
branch in my public git tree. My 'v2' never saw the light of day
because I kept cleaning it up, but an earlier version with some more
background is available under the name 'noref-filemap-read-with-llm'
and has an empty commit with more commentary and background at the
top. I didn't do that cover-letter for this v3 version, and it talks
about some issues that already got resolved (and others that I don't
think are actual real problems, but should be discussed).

The fairly short series of ten patches basically enhances folio lookup
by noticing when folios are hot, and setting a "delay relasing this
folio until after a RCU period", and then using that RCU delay it does
not just the folio lookup itself under RCU (which we've done forever),
but also the actual folio data accesses themselves under RCU. No
refcount taking needed for the fastpath where we can just read the
data from the folio entirely in an RCU-protected region when the user
copy doesn't cause page faults.

Unlike my original approach - because it now actually delays the
freeing of the underlying folio data - there's no need for any double
buffering, and a lot of the original limitations of my original patch
go away too. That improves performance quite a lot. And by "quite a
lot"  I mean "I see a 23x performance increase on my Ryzen
threadripper". Admittedly that is a very artificial case of reading
the same small part of a page over and over in a threaded loop on all
CPUs, so any real life impact will be much much less.

Anyway, I wasn't planning on posting the individual patches, I think
we all use git by now and probably find it easier than fetching
patches from the list. So it's all at

    git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux rcu-free-v3

and the commit messages are a bit more verbose than I would have done
it myself without tool use, but maybe it's better that way.

The showcase number is in the "mm/filemap: read from the page cache
without folio references" commit:

                               reads/s     cycles    instructions
                                          per read     per read
   ...
  64 threads,           before   13.3 M  19857-19939   1094-1101
  64 threads,           after    304 M     735-736        959

ie the number of reads per second had plateaued at 13.3M due to the
cacheline contention on the folio reference count (and the cycles per
read had ballooned up to 20k).

And with that scalability limiter gone, it zooms up to 304M.

And again - that's not a real number in the sense that no real load
will ever see it, but the takeaway is that it basically scales
perfectly with no writes to shared cachelines. And honestly, the
patches don't look bad, and it's possible that other cases might find
use for this RCU-delayed page freeing.

Comments?

                Linus


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-10-14 13:59 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 18:43 Improve page refcount scalability Linus Torvalds
2026-10-13 21:03 ` Matthew Wilcox
2026-10-13 21:26   ` Linus Torvalds
2026-10-13 23:20   ` Paul E. McKenney
2026-10-14 10:36   ` Kiryl Shutsemau
2026-10-14 10:46     ` David Hildenbrand (Arm)
2026-10-13 22:43 ` Kiryl Shutsemau
2026-10-13 23:39   ` Linus Torvalds
2026-10-14 11:53     ` Kiryl Shutsemau
2026-10-14  0:10 ` Harry Yoo
2026-10-14  1:01   ` Linus Torvalds
2026-10-14 13:59     ` Pedro Falcato

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.