Re: Improve page refcount scalability

From: Linus Torvalds

Date: Wed Oct 14 2026 - 13:03:27 EST


On Wed, 14 Oct 2026 at 09:25, Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> > How many pages (as a %) are you seeing as marked PG_rcu_free across a boot/
> > realistic workload?
>
> I haven't actually checked outside of "a normal boot doesn't cause
> even a single accelerated RCU period". But I'll go reboot into a clean
> kernel and see what a kernel compile does.

So for me, after a boot into a full desktop environment and starting
google-chrome with my usual setup (18 tabs open), I have

nr_free_rcu 0
pgfree_rcu 73
pgfree_rcu_done 70
pgfree_rcu_mark 34038
pgfree_rcu_kick 0
pgfree_rcu_drain 0

IOW, I have 135MB marked for PG_rcu_free - sounds reasonable - but
zero actual expedited RCU events.

And then, after having done a full kernel allmodconfig build ("git
clean -dqfx" + "make allmodconfig" + "make -j60"), the numbers grow,
but:

nr_free_rcu 0
pgfree_rcu 32107
pgfree_rcu_done 32107
pgfree_rcu_mark 1395272
pgfree_rcu_kick 0
pgfree_rcu_drain 0

so a fair amount of activity, but this machine has obviously never
been under any memory pressure.

What do these numbers tell me? Not a lot. That pgfree_rcu_mark number
is cumulative and keeps growing forever - it's just the count of pages
that have ever been marked. And the best way to grow the
pgfree_rcu_done numbers is actually to then do a "git clean -dqfx",
because that will delete all the generated files - and that was a lot
of the RCU marked data, so now it will be free'd.

That actually makes me think I should go back and clear PG_rcu_free on
unlink - at that point the folio can no longer be read. I used to
treat unlink differently from truncate/hole punch because of this, but
that was in my first version where I marked the pages for freeing when
removing them from the address space. Now that I mark them at read
time when they are 'hot', unlink() is still going to pointlessly
rcu-delay their freeing.

Let me look at that.

But the short of it is: normal loads without any real memory pressure
simply don't cause a lot of actual RCU events at all.

Linus