* [PATCH v4 0/3] mm: hugetlb: fix CMA-related issues
@ 2026-11-11 6:46 Qi Zheng
2026-11-11 6:46 ` [PATCH v4 1/3] x86: hugetlb: disable default CMA reservations on 32-bit kernel Qi Zheng
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Qi Zheng @ 2026-11-11 6:46 UTC (permalink / raw)
To: muchun.song, osalvador, david, akpm, azpijr, lance.yang
Cc: linux-kernel, linux-mm, Qi Zheng
From: Qi Zheng <zhengqi.arch@bytedance.com>
Hi all,
This series fixes three CMA-related issues in HugeTLB reservation,
long-term pinning and allocation:
- Avoid ineffective CMA reservations on 32-bit x86 kernels running on
CPUs that advertise 1 GiB page support.
- Allow long-term pins of explicitly CMA-allocated HugeTLB folios,
which already own the CMA memory.
- Preserve the caller's GFP mask when allocating from CMA.
Changes in v4:
- add comment to cma_alloc_frozen_compound().
(suggested by Oscar Salvador)
- collect Reviewed-by tag.
- rebase onto next-20261110.
Changes in v3:
- Drop the cpuset fix. A more comprehensive fix across the HugeTLB
allocation paths will follow in a separate patchset.
- Check for __GFP_COMP instead of adding it in
cma_alloc_frozen_compound(), and leave __GFP_NOWARN to callers.
(suggested by Oscar Salvador)
- Clarify the CMA ownership comment in folio_is_longterm_pinnable().
(suggested by Muchun Song)
- Collect Reviewed-by and Acked-by tags.
Changes in v2:
- Replace the PF_MEMALLOC_PIN allocation restriction with a GUP exception
for HugeTLB folios marked HPG_cma. (suggested by Muchun Song)
- Pass the caller's GFP mask through cma_alloc_frozen_compound() instead
of skipping CMA when direct reclaim is disallowed.
(suggested by sashiko)
- Remove unnecessary revalidation of successfully allocated folios after
cpuset changes. Retry only failed allocations.
(pointed by Jose A. Perez de Azpillaga)
- collect Reviewed-by and Acked-by.
- Rebase onto next-20261104.
Thanks,
Qi
Qi Zheng (3):
x86: hugetlb: disable default CMA reservations on 32-bit kernel
mm: gup: allow long-term pins of CMA-allocated HugeTLB folios
mm: hugetlb: fix GFP mask propagation to CMA
arch/x86/mm/hugetlbpage.c | 2 +-
include/linux/cma.h | 2 +-
include/linux/mm.h | 29 +----------------------------
mm/cma.c | 10 ++++++++--
mm/gup.c | 31 +++++++++++++++++++++++++++++++
mm/hugetlb_cma.c | 4 ++--
6 files changed, 44 insertions(+), 34 deletions(-)
base-commit: 793807ca13bf3072fc6d16ce6d90e9ab9beff2a5
--
2.54.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 1/3] x86: hugetlb: disable default CMA reservations on 32-bit kernel
2026-11-11 6:46 [PATCH v4 0/3] mm: hugetlb: fix CMA-related issues Qi Zheng
@ 2026-11-11 6:46 ` Qi Zheng
2026-11-11 6:46 ` [PATCH v4 2/3] mm: gup: allow long-term pins of CMA-allocated HugeTLB folios Qi Zheng
2026-11-11 6:46 ` [PATCH v4 3/3] mm: hugetlb: fix GFP mask propagation to CMA Qi Zheng
2 siblings, 0 replies; 6+ messages in thread
From: Qi Zheng @ 2026-11-11 6:46 UTC (permalink / raw)
To: muchun.song, osalvador, david, akpm, azpijr, lance.yang
Cc: linux-kernel, linux-mm, Qi Zheng, stable
From: Qi Zheng <zhengqi.arch@bytedance.com>
A 32-bit x86 kernel can run on a 64-bit-capable CPU advertising GBPAGES.
arch_hugetlb_cma_order() checks only this feature and returns a nonzero
order, although gigantic HugeTLB support on x86 requires CONFIG_X86_64.
Specifying hugetlb_cma= can therefore reserve a CMA area that cannot
serve the intended gigantic HugeTLB allocations.
On non-PAE kernels, the folded PUD_SHIFT yields a 4 MiB order, which is
equal to MAX_PAGE_ORDER. With CONFIG_DEBUG_VM enabled, this triggers the
VM_WARN_ON(order <= MAX_PAGE_ORDER) check in hugetlb_cma_reserve(),
warning that hugetlb_cma is attempting to reserve a non-gigantic order.
Require CONFIG_X86_64 as well as GBPAGES when selecting the default CMA
order to avoid these ineffective reservations.
Fixes: cf11e85fc08c ("mm: hugetlb: optionally allocate gigantic hugepages using cma")
Cc: stable@vger.kernel.org
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Acked-by: Oscar Salvador <osalvador@suse.de>
---
arch/x86/mm/hugetlbpage.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index 3b26621c91286..70726a99ede7b 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -45,7 +45,7 @@ arch_initcall(gigantic_pages_init);
unsigned int __init arch_hugetlb_cma_order(void)
{
- if (boot_cpu_has(X86_FEATURE_GBPAGES))
+ if (IS_ENABLED(CONFIG_X86_64) && boot_cpu_has(X86_FEATURE_GBPAGES))
return PUD_SHIFT - PAGE_SHIFT;
return 0;
--
2.54.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 2/3] mm: gup: allow long-term pins of CMA-allocated HugeTLB folios
2026-11-11 6:46 [PATCH v4 0/3] mm: hugetlb: fix CMA-related issues Qi Zheng
2026-11-11 6:46 ` [PATCH v4 1/3] x86: hugetlb: disable default CMA reservations on 32-bit kernel Qi Zheng
@ 2026-11-11 6:46 ` Qi Zheng
2026-11-11 7:42 ` David Hildenbrand (Arm)
2026-11-11 7:42 ` Muchun Song
2026-11-11 6:46 ` [PATCH v4 3/3] mm: hugetlb: fix GFP mask propagation to CMA Qi Zheng
2 siblings, 2 replies; 6+ messages in thread
From: Qi Zheng @ 2026-11-11 6:46 UTC (permalink / raw)
To: muchun.song, osalvador, david, akpm, azpijr, lance.yang
Cc: linux-kernel, linux-mm, Qi Zheng, stable
From: Qi Zheng <zhengqi.arch@bytedance.com>
Long-term pinning treats explicitly CMA-allocated HugeTLB folios as
unpinnable, causing unnecessary migration or pinning failures.
These folios already own their CMA bitmap ranges, and memory blocks
overlapping CMA areas cannot be offlined. Allow HugeTLB folios with
HPG_cma to be pinned directly, including in ZONE_MOVABLE.
Fixes: cf11e85fc08c ("mm: hugetlb: optionally allocate gigantic hugepages using cma")
Cc: stable@vger.kernel.org
Suggested-by: Muchun Song <muchun.song@linux.dev>
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Oscar Salvador <osalvador@suse.de>
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
---
include/linux/mm.h | 29 +----------------------------
mm/gup.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 28 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index b0da9be413098..47d1d96bfc7fd 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2954,35 +2954,8 @@ static inline bool is_zero_folio(const struct folio *folio)
return is_zero_page(&folio->page);
}
-/* MIGRATE_CMA and ZONE_MOVABLE do not allow pin folios */
#ifdef CONFIG_MIGRATION
-static inline bool folio_is_longterm_pinnable(struct folio *folio)
-{
-#ifdef CONFIG_CMA
- int mt = folio_migratetype(folio);
-
- if (mt == MIGRATE_CMA || mt == MIGRATE_ISOLATE)
- return false;
-#endif
- /* The zero page can be "pinned" but gets special handling. */
- if (is_zero_folio(folio))
- return true;
-
- /* Coherent device memory must always allow eviction. */
- if (folio_is_device_coherent(folio))
- return false;
-
- /*
- * Filesystems can only tolerate transient delays to truncate and
- * hole-punch operations
- */
- if (folio_is_fsdax(folio))
- return false;
-
- /* Otherwise, non-movable zone folios can be pinned. */
- return !folio_is_zone_movable(folio);
-
-}
+bool folio_is_longterm_pinnable(struct folio *folio);
#else
static inline bool folio_is_longterm_pinnable(struct folio *folio)
{
diff --git a/mm/gup.c b/mm/gup.c
index ebbfee09b7278..fdafc5a1b78ed 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -2219,6 +2219,37 @@ struct page *get_dump_page(unsigned long addr, int *locked)
#ifdef CONFIG_MIGRATION
+bool folio_is_longterm_pinnable(struct folio *folio)
+{
+#ifdef CONFIG_CMA
+ int mt = folio_migratetype(folio);
+
+ /* These HugeTLB folios own the CMA memory, so they can be long-term pinned. */
+ if (folio_test_hugetlb(folio) && folio_test_hugetlb_cma(folio))
+ return true;
+
+ if (mt == MIGRATE_CMA || mt == MIGRATE_ISOLATE)
+ return false;
+#endif
+ /* The zero page can be "pinned" but gets special handling. */
+ if (is_zero_folio(folio))
+ return true;
+
+ /* Coherent device memory must always allow eviction. */
+ if (folio_is_device_coherent(folio))
+ return false;
+
+ /*
+ * Filesystems can only tolerate transient delays to truncate and
+ * hole-punch operations
+ */
+ if (folio_is_fsdax(folio))
+ return false;
+
+ /* Otherwise, non-movable zone folios can be pinned. */
+ return !folio_is_zone_movable(folio);
+}
+
/*
* An array of either pages or folios ("pofs"). Although it may seem tempting to
* avoid this complication, by simply interpreting a list of folios as a list of
--
2.54.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 3/3] mm: hugetlb: fix GFP mask propagation to CMA
2026-11-11 6:46 [PATCH v4 0/3] mm: hugetlb: fix CMA-related issues Qi Zheng
2026-11-11 6:46 ` [PATCH v4 1/3] x86: hugetlb: disable default CMA reservations on 32-bit kernel Qi Zheng
2026-11-11 6:46 ` [PATCH v4 2/3] mm: gup: allow long-term pins of CMA-allocated HugeTLB folios Qi Zheng
@ 2026-11-11 6:46 ` Qi Zheng
2 siblings, 0 replies; 6+ messages in thread
From: Qi Zheng @ 2026-11-11 6:46 UTC (permalink / raw)
To: muchun.song, osalvador, david, akpm, azpijr, lance.yang
Cc: linux-kernel, linux-mm, Qi Zheng, stable, Oscar Salvador (SUSE)
From: Qi Zheng <zhengqi.arch@bytedance.com>
cma_alloc_frozen_compound() uses GFP_KERNEL, allowing direct reclaim
during the first MPOL_PREFERRED_MANY allocation attempt even though
the caller clears __GFP_DIRECT_RECLAIM.
Pass the caller's GFP mask through the helper so CMA respects its
reclaim constraints when trying the preferred nodes.
Fixes: 9bda131c6093 ("mm: cma: add cma_alloc_frozen{_compound}()")
Cc: stable@vger.kernel.org
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Reviewed-by: Oscar Salvador (SUSE) <osalvador@kernel.org>
---
include/linux/cma.h | 2 +-
mm/cma.c | 10 ++++++++--
mm/hugetlb_cma.c | 4 ++--
3 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/include/linux/cma.h b/include/linux/cma.h
index 8555d38a97b1a..4539ea5f2c4e8 100644
--- a/include/linux/cma.h
+++ b/include/linux/cma.h
@@ -53,7 +53,7 @@ extern bool cma_release(struct cma *cma, const struct page *pages, unsigned long
struct page *cma_alloc_frozen(struct cma *cma, unsigned long count,
unsigned int align, bool no_warn);
-struct page *cma_alloc_frozen_compound(struct cma *cma, unsigned int order);
+struct page *cma_alloc_frozen_compound(struct cma *cma, unsigned int order, gfp_t gfp);
bool cma_release_frozen(struct cma *cma, const struct page *pages,
unsigned long count);
diff --git a/mm/cma.c b/mm/cma.c
index 9ec1d1fd5dff5..a7c47c0e7d070 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -933,9 +933,15 @@ struct page *cma_alloc_frozen(struct cma *cma, unsigned long count,
return __cma_alloc_frozen(cma, count, align, gfp);
}
-struct page *cma_alloc_frozen_compound(struct cma *cma, unsigned int order)
+struct page *cma_alloc_frozen_compound(struct cma *cma, unsigned int order, gfp_t gfp)
{
- gfp_t gfp = GFP_KERNEL | __GFP_COMP | __GFP_NOWARN;
+ /*
+ * The only caller of cma_alloc_frozen_compound() is hugetlb, and
+ * hugetlb constructs its gfp mask via htlb_alloc_mask(), which already
+ * sets __GFP_COMP. Check here for usecases bypassing htlb_alloc_mask().
+ */
+ if (WARN_ON_ONCE(!(gfp & __GFP_COMP)))
+ return NULL;
return __cma_alloc_frozen(cma, 1 << order, order, gfp);
}
diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
index cd6a64986278a..3e5a30571524a 100644
--- a/mm/hugetlb_cma.c
+++ b/mm/hugetlb_cma.c
@@ -69,14 +69,14 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
}
if (hugetlb_cma[nid] && node_isset(nid, *nmask))
- page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
+ page = cma_alloc_frozen_compound(hugetlb_cma[nid], order, gfp_mask);
if (!page && !(gfp_mask & __GFP_THISNODE)) {
for_each_node_mask(node, *nmask) {
if (node == nid || !hugetlb_cma[node])
continue;
- page = cma_alloc_frozen_compound(hugetlb_cma[node], order);
+ page = cma_alloc_frozen_compound(hugetlb_cma[node], order, gfp_mask);
if (page)
break;
}
--
2.54.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/3] mm: gup: allow long-term pins of CMA-allocated HugeTLB folios
2026-11-11 6:46 ` [PATCH v4 2/3] mm: gup: allow long-term pins of CMA-allocated HugeTLB folios Qi Zheng
@ 2026-11-11 7:42 ` David Hildenbrand (Arm)
2026-11-11 7:42 ` Muchun Song
1 sibling, 0 replies; 6+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-11 7:42 UTC (permalink / raw)
To: Qi Zheng, muchun.song, osalvador, akpm, azpijr, lance.yang
Cc: linux-kernel, linux-mm, Qi Zheng, stable
On 11/11/26 07:46, Qi Zheng wrote:
> From: Qi Zheng <zhengqi.arch@bytedance.com>
>
> Long-term pinning treats explicitly CMA-allocated HugeTLB folios as
> unpinnable, causing unnecessary migration or pinning failures.
>
> These folios already own their CMA bitmap ranges, and memory blocks
> overlapping CMA areas cannot be offlined. Allow HugeTLB folios with
> HPG_cma to be pinned directly, including in ZONE_MOVABLE.
You should really describe here what this patch does (move stuff) and why, and
document why you decided to add more hugetlb hacks to core-MM that I absolutely
hate.
--
Cheers,
David
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v4 2/3] mm: gup: allow long-term pins of CMA-allocated HugeTLB folios
2026-11-11 6:46 ` [PATCH v4 2/3] mm: gup: allow long-term pins of CMA-allocated HugeTLB folios Qi Zheng
2026-11-11 7:42 ` David Hildenbrand (Arm)
@ 2026-11-11 7:42 ` Muchun Song
1 sibling, 0 replies; 6+ messages in thread
From: Muchun Song @ 2026-11-11 7:42 UTC (permalink / raw)
To: Qi Zheng
Cc: osalvador, David Hildenbrand, akpm, azpijr, Lance Yang,
linux-kernel, linux-mm, Qi Zheng, stable
> On Nov 11, 2026, at 14:46, Qi Zheng <qi.zheng@linux.dev> wrote:
>
> From: Qi Zheng <zhengqi.arch@bytedance.com>
>
> Long-term pinning treats explicitly CMA-allocated HugeTLB folios as
> unpinnable, causing unnecessary migration or pinning failures.
>
> These folios already own their CMA bitmap ranges, and memory blocks
Commit message needs updating to bitmap as well.
> overlapping CMA areas cannot be offlined. Allow HugeTLB folios with
> HPG_cma to be pinned directly, including in ZONE_MOVABLE.
>
> Fixes: cf11e85fc08c ("mm: hugetlb: optionally allocate gigantic hugepages using cma")
> Cc: stable@vger.kernel.org
> Suggested-by: Muchun Song <muchun.song@linux.dev>
> Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
> Acked-by: Muchun Song <muchun.song@linux.dev>
> Reviewed-by: Oscar Salvador <osalvador@suse.de>
> Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
> ---
> include/linux/mm.h | 29 +----------------------------
> mm/gup.c | 31 +++++++++++++++++++++++++++++++
> 2 files changed, 32 insertions(+), 28 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index b0da9be413098..47d1d96bfc7fd 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2954,35 +2954,8 @@ static inline bool is_zero_folio(const struct folio *folio)
> return is_zero_page(&folio->page);
> }
>
> -/* MIGRATE_CMA and ZONE_MOVABLE do not allow pin folios */
> #ifdef CONFIG_MIGRATION
> -static inline bool folio_is_longterm_pinnable(struct folio *folio)
I think David prefer to move this function first, then fix it in a separate patch,
right?
Thanks,
Muchun
> -{
> -#ifdef CONFIG_CMA
> - int mt = folio_migratetype(folio);
> -
> - if (mt == MIGRATE_CMA || mt == MIGRATE_ISOLATE)
> - return false;
> -#endif
> - /* The zero page can be "pinned" but gets special handling. */
> - if (is_zero_folio(folio))
> - return true;
> -
> - /* Coherent device memory must always allow eviction. */
> - if (folio_is_device_coherent(folio))
> - return false;
> -
> - /*
> - * Filesystems can only tolerate transient delays to truncate and
> - * hole-punch operations
> - */
> - if (folio_is_fsdax(folio))
> - return false;
> -
> - /* Otherwise, non-movable zone folios can be pinned. */
> - return !folio_is_zone_movable(folio);
> -
> -}
> +bool folio_is_longterm_pinnable(struct folio *folio);
> #else
> static inline bool folio_is_longterm_pinnable(struct folio *folio)
> {
> diff --git a/mm/gup.c b/mm/gup.c
> index ebbfee09b7278..fdafc5a1b78ed 100644
> --- a/mm/gup.c
> +++ b/mm/gup.c
> @@ -2219,6 +2219,37 @@ struct page *get_dump_page(unsigned long addr, int *locked)
>
> #ifdef CONFIG_MIGRATION
>
> +bool folio_is_longterm_pinnable(struct folio *folio)
> +{
> +#ifdef CONFIG_CMA
> + int mt = folio_migratetype(folio);
> +
> + /* These HugeTLB folios own the CMA memory, so they can be long-term pinned. */
> + if (folio_test_hugetlb(folio) && folio_test_hugetlb_cma(folio))
> + return true;
> +
> + if (mt == MIGRATE_CMA || mt == MIGRATE_ISOLATE)
> + return false;
> +#endif
> + /* The zero page can be "pinned" but gets special handling. */
> + if (is_zero_folio(folio))
> + return true;
> +
> + /* Coherent device memory must always allow eviction. */
> + if (folio_is_device_coherent(folio))
> + return false;
> +
> + /*
> + * Filesystems can only tolerate transient delays to truncate and
> + * hole-punch operations
> + */
> + if (folio_is_fsdax(folio))
> + return false;
> +
> + /* Otherwise, non-movable zone folios can be pinned. */
> + return !folio_is_zone_movable(folio);
> +}
> +
> /*
> * An array of either pages or folios ("pofs"). Although it may seem tempting to
> * avoid this complication, by simply interpreting a list of folios as a list of
> --
> 2.54.0
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-11-11 7:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11 6:46 [PATCH v4 0/3] mm: hugetlb: fix CMA-related issues Qi Zheng
2026-11-11 6:46 ` [PATCH v4 1/3] x86: hugetlb: disable default CMA reservations on 32-bit kernel Qi Zheng
2026-11-11 6:46 ` [PATCH v4 2/3] mm: gup: allow long-term pins of CMA-allocated HugeTLB folios Qi Zheng
2026-11-11 7:42 ` David Hildenbrand (Arm)
2026-11-11 7:42 ` Muchun Song
2026-11-11 6:46 ` [PATCH v4 3/3] mm: hugetlb: fix GFP mask propagation to CMA Qi Zheng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®