Thread (24 messages) 24 messages, 7 authors, 2026-01-13

Re: [PATCH v4 1/7] mm/zone_device: Add order argument to folio_free callback

From: Zi Yan <ziy@nvidia.com>
Date: 2026-01-12 18:55:31
Also in: amd-gfx, dri-devel, intel-xe, kvm, linux-cxl, linux-mm, linux-pci, lkml, nouveau

On 12 Jan 2026, at 13:25, Jason Gunthorpe wrote:
On Mon, Jan 12, 2026 at 12:46:57PM -0500, Zi Yan wrote:
quoted
On 12 Jan 2026, at 11:50, Jason Gunthorpe wrote:
quoted
On Mon, Jan 12, 2026 at 11:31:04AM -0500, Zi Yan wrote:
quoted
quoted
folio_free()

1) Allocator finds free memory
2) zone_device_page_init() allocates the memory and makes refcount=1
3) __folio_put() knows the recount 0.
4) free_zone_device_folio() calls folio_free(), but it doesn't
   actually need to undo prep_compound_page() because *NOTHING* can
   use the page pointer at this point.
5) Driver puts the memory back into the allocator and now #1 can
   happen. It knows how much memory to put back because folio->order
   is valid from #2
6) #1 happens again, then #2 happens again and the folio is in the
   right state for use. The successor #2 fully undoes the work of the
   predecessor #2.
But how can a successor #2 undo the work if the second #1 only allocates
half of the original folio? For example, an order-9 at PFN 0 is
allocated and freed, then an order-8 at PFN 0 is allocated and another
order-8 at PFN 256 is allocated. How can two #2s undo the same order-9
without corrupting each other’s data?
What do you mean? The fundamental rule is you can't read the folio or
the order outside folio_free once it's refcount reaches 0.
There is no such a rule. In core MM, folio_split(), which splits a high
order folio to low order ones, freezes the folio (turning refcount to 0)
and manipulates the folio order and all tail pages compound_head to
restructure the folio.
That's different, I am talking about reaching 0 because it has been
freed, meaning there are no external pointers to it.

Further, when a page is frozen page_ref_freeze() takes in the number
of references the caller has ownership over and it doesn't succeed if
there are stray references elsewhere.

This is very important because the entire operating model of split
only works if it has exclusive locks over all the valid pointers into
that page.

Spurious refcount failures concurrent with split cannot be allowed.

I don't see how pointing at __folio_freeze_and_split_unmapped() can
justify this series.
But from anyone looking at the folio state, refcount == 0, compound_head
is set, they cannot tell the difference.

If what you said is true, why is free_pages_prepare() needed? No one
should touch these free pages. Why bother resetting these states.
quoted
Your fundamental rule breaks this.  Allowing compound information
to stay after a folio is freed means you cannot tell whether a folio
is under split or freed.
You can't refcount a folio out of nothing. It has to come from a
memory location that already is holding a refcount, and then you can
incr it.
Right. There is also no guarantee that all code is correct and follows
this.

My point here is that calling prep_compound_page() on a compound page
does not follow core MM’s conventions.

Best Regards,
Yan, Zi
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help