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));
>>
>> /*