Re: [PATCH v5 1/3] mm/page_alloc: Optimize free_contig_range()

From: David Hildenbrand (Arm)

Date: Wed Apr 01 2026 - 06:04:45 EST


>> +static void free_prepared_contig_range(struct page *page,
>> + unsigned long nr_pages)
>> +{
>> + while (nr_pages) {
>> + unsigned long pfn = page_to_pfn(page);
>
> Sorry for not noticing earlier. I now realized that because here we are
> guaranteed to be restricted to the same section, we can do page_to_pfn()
> just once outside the loop and then "pfn += 1UL << order;" below?

+1

>
>> + unsigned int order;
>> +
>> + /* We are limited by the largest buddy order. */
>> + order = pfn ? __ffs(pfn) : MAX_PAGE_ORDER;
>> + /* Don't exceed the number of pages to free. */
>> + order = min_t(unsigned int, order, ilog2(nr_pages));
>> + order = min_t(unsigned int, order, MAX_PAGE_ORDER);
>> +
>> + /*
>> + * Free the chunk as a single block. Our caller has already
>> + * called free_pages_prepare() for each order-0 page.
>> + */
>> + __free_frozen_pages(page, order, FPI_PREPARED);
>> +
>> + page += 1UL << order;
>> + nr_pages -= 1UL << order;
>> + }
>> +}
>> +
>> +static void __free_contig_range_common(unsigned long pfn, unsigned long nr_pages,
>> + bool is_frozen)
>> +{
>> + struct page *page, *start = NULL;
>> + unsigned long nr_start = 0;
>> + unsigned long start_sec;
>> + unsigned long i;
>> +
>> + for (i = 0; i < nr_pages; i++) {
>> + bool can_free = true;
>> +
>> + /*
>> + * Contiguous PFNs might not have contiguous "struct pages"
>> + * in some kernel configs: page++ across a section boundary
>> + * is undefined. Use pfn_to_page() for each PFN.
>> + */
>> + page = pfn_to_page(pfn + i);
>
> Hm ideally we'd have some pfn+page iterator thingy that would just do a
> page++ on configs where it's contiguous and this more expensive operation
> otherwise. Wonder why we don't have it yet. But that's for a possible
> followup, not required now.

pfn_to_page() is on relevant configs close to just a "page + i". Not
entirely, but I am not sure if the micro-gain would really be worth it.

E.g., on CONFIG_SPARSEMEM_VMEMMAP

#define __pfn_to_page(pfn) vmemmap + (pfn)


Acked-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>

--
Cheers,

David