On 12 Jan 2026, at 13:25, Jason Gunthorpe wrote: > On Mon, Jan 12, 2026 at 12:46:57PM -0500, Zi Yan wrote: >> On 12 Jan 2026, at 11:50, Jason Gunthorpe wrote: >> >>> On Mon, Jan 12, 2026 at 11:31:04AM -0500, Zi Yan wrote: >>>>> 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. >> 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
