Re: [PATCH v3 21/26] mm/page_alloc: implement FREETYPE_UNMAPPED allocations

"Brendan Jackman" <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.kernel.mm
Message-ID <[email protected]>
On Wed Aug 12, 2026 at 10:26 PM BST, Yosry Ahmed wrote:
> [..]
>>  static __always_inline
>>  struct page *rmqueue_buddy(struct zone *preferred_zone, struct zone *zone,
>>  			   unsigned int order, unsigned int alloc_flags,
>> @@ -3433,13 +3580,15 @@ struct page *rmqueue_buddy(struct zone *preferred_zone, struct zone *zone,
>>  			 */
>>  			if (!page && (alloc_flags & (ALLOC_OOM|ALLOC_HARDER)))
>>  				page = __rmqueue_smallest(zone, order, ft_high);
>> -
>> -			if (!page) {
>> -				spin_unlock_irqrestore(&zone->lock, flags);
>> -				return NULL;
>> -			}
>>  		}
>>  		spin_unlock_irqrestore(&zone->lock, flags);
>> +
>> +		/* Try changing direct map, now we've released the zone lock */
>> +		if (!page)
>> +			page = __rmqueue_direct_map(zone, order, alloc_flags, freetype);
>
> Is it intentional that this is called outside __rmqueue() and doesn't
> cover pcplists refills through rmqueue_bulk()?
>
> IIUC, we will never change a pageblock to unmapped to refill the
> pcplists, so the unmapped pcplists can get filled in two ways:
> (a) When unmapped pages are freed.
> (b) When a pageblock is converted here (in rmqueue_buddy()), if the
>     allocation only consumes part of it, the new allocation might move
>     the rest into the pcplist through rmqueue_bulk().
>
> Does this mean that unmapped pcplists are less effective in serving
> allocations? There is a tradeoff here because converting a pageblock to
> unmapped is expensive, so maybe this is the right choice to make, I am
> just wondering if this was intentional and/or if we tried it a different
> way.

Yeah I think this is all aligned with how I envisaged this working. I
have been assuming that changing pageblocks only happens:

1. When botting / changing between different kinds of workload.

2. When the system is quite distressed by memory pressure.

I think in both cases, proactively flipping a block just to refill
pcplists is unhelpful?

> Actuall, THPs are not covered by scenario (b) above if the pageblock
> size is the same as THP size, as the converted THPs are always consumed
> by the allocation, so the THP pcplist will only be filled when THPs are
> freed.
>
> I wonder if this would cause a problem for THP-heavy workloads (e.g.
> guest_memfd using THP, or any THP usage with ASI).

And again it doesn't feel right to proactively flip a block just to
create a pcplist. The cost of a pcplist miss is basically a bit of
cacheline contention while the cost of flipping a block is pretty high,
it seems well worth risking the former to avoid the latter.

> The other thing (that I probably mentioned elsewhere) is that kcompactd
> does not produce unmapped pageblocks, so it seems like THP allocations
> will mostly hit this code path and convert a pageblock to unmapped.

Yeah, I think making kcompactd produce unmapped blocks is a nice
standalone optimisation series and it can probably wait until someone
has a workload they can share the performance improvements from.

> Actually, if we do bulk conversion to unmapped (e.g. in kcompactd) we
> could batch the TLB shootdowns as well, but that should probably be done
> separately.

Oh, that's a good point though, coz that would also interact nicely with
pcplists. In theory we could allocate several contiguous pageblocks,
flip them with a single amortised flush, and then use that to refill
pcplists. But yeah this still feels like far future optimisations if and
when we actually knew it helped.

>> +		if (!page)
>> +			return NULL;
>> +
>>  	} while (check_new_pages(page, order));
>>  
>>  	/*
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.