Re: [PATCH 2/4] mm: hugetlb: skip CMA allocations under PF_MEMALLOC_PIN
From: Muchun Song
Date: Tue Nov 03 2026 - 07:50:57 EST
> On Nov 3, 2026, at 16:01, Qi Zheng <qi.zheng@xxxxxxxxx> wrote:
>
> From: Qi Zheng <zhengqi.arch@xxxxxxxxxxxxx>
>
> With gigantic overcommit enabled, a fault during long-term pinning
> can allocate a fresh HugeTLB folio from CMA despite PF_MEMALLOC_PIN.
>
> The folio must then be migrated before it can be pinned. However,
> fresh gigantic migration targets are not supported, so pinning fails
> when the HugeTLB pool has no suitable target, even if the original
> fault could have allocated pinnable memory outside CMA.
>
> Honor PF_MEMALLOC_PIN in the HugeTLB CMA allocator so the fault can
> try the non-CMA fallback, or fail when allocation is restricted to CMA.
Wait... I think my Acked-by got ahead of me here. :)
There seems to be a rather odd distinction that GUP is missing.
The usual reason long-term GUP must migrate a page out of a
MIGRATE_CMA pageblock is that the page was only borrowed from CMA by the
normal page allocator. The corresponding CMA bitmap range is still
available, so a future CMA allocation relies on being able to migrate
that page away. A long-term pin would prevent that.
However, a HugeTLB folio returned by
hugetlb_cma_alloc_frozen_folio() is different. It is the actual CMA
allocation, not merely a movable page that happens to reside in a
MIGRATE_CMA pageblock. Its range has already been marked allocated in
the hugetlb CMA bitmap.
Therefore, CMA cannot allocate that range again until the HugeTLB folio
is freed anyway. Long-term pinning the folio does not seem to make the
CMA area any less available than keeping the HugeTLB folio mapped for
the same amount of time.
folio_is_longterm_pinnable() currently only sees MIGRATE_CMA and does
not distinguish these two cases. In that light, rejecting
PF_MEMALLOC_PIN in hugetlb_cma_alloc_frozen_folio() looks like working
around an overly broad GUP classification. It also means that
hugetlb_cma_only users will fail the fault, while other users may consume
a gigantic contiguous range outside the dedicated hugetlb CMA area even
when that area has free space.
Would it make more sense to fix the long-term GUP check instead, so that
an explicitly CMA-allocated HugeTLB folio is considered pinnable, while
ordinary pages merely borrowed from MIGRATE_CMA pageblocks remain unpinnable?
Thanks,
Muchun
>
> Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Qi Zheng <zhengqi.arch@xxxxxxxxxxxxx>
> ---
> mm/hugetlb_cma.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> index 95fd2d190f0d2..dde1c866406fb 100644
> --- a/mm/hugetlb_cma.c
> +++ b/mm/hugetlb_cma.c
> @@ -62,6 +62,9 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> if (!hugetlb_cma_size)
> return NULL;
>
> + if (current->flags & PF_MEMALLOC_PIN)
> + return NULL;
> +
> retry_cpuset:
> if (!nodemask) {
> cpuset_mems_cookie = read_mems_allowed_begin();
> --
> 2.54.0
>