Re: [PATCH v4 0/2] mm: improve folio refcount scalability
From: David Hildenbrand (Arm)
Date: Mon Jun 22 2026 - 04:22:24 EST
On 6/21/26 06:46, Linus Torvalds wrote:
> On Sat, 20 Jun 2026 at 11:19, <ilya.gladyshev@xxxxxxxxx> wrote:
>>
>> T2: optimistic get() [0 -> 1]
>> T2: put page back [1 -> 0]
>> T2: calls dtor for type X, returns into the allocator
>
> Which optimistic getter does this?
>
> I didn't go back and look at the series, but isn't the rule that the code does:
>
> - optimistic get
>
> - then check that the folio is still valid (*not* using the page
> count, but by re-looking it up elsewhere, typically the address space
> mapping)
>
> - put the page if it wasn't valid
>
> - if it goes to zero, there's no destructor inherent in that
I'm also confused about the destructor aspect. Usually we have
folio_try_get(folio)
... some checks
folio_put(folio);
folio_put() is just:
if (folio_put_testzero(folio))
__folio_put(folio);
If the thing was a folio at the start, but stopped being a folio halfway through
folio_put(), I don't see the big difference to the thing not being a folio right
from the start. (folio_try_get() would succeed on some random page either way
right now)
Which destructors are we concerned about?
(1) hugetlb destructor
If we grabbed a non-hugetlb folio but suddenly have a hugetlb folio after
folio_put_testzero(), __folio_put() will just do the right thing and call
free_huge_folio().
(2) pagetable_dtor()
These destructors are called when we unmap the page table, before actually
freeing it. So it wouldn't apply here.
Maybe it's about something like
void page_frag_free(void *addr)
{
struct page *page = virt_to_head_page(addr);
if (unlikely(put_page_testzero(page)))
free_frozen_pages(page, compound_order(page));
}
Whereby, if it's a folio, we wouldn't do the right thing as we are
not going through __folio_put()?
--
Cheers,
David