mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Muchun Song <muchun.song@linux.dev>
To: Qi Zheng <qi.zheng@linux.dev>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Qi Zheng <zhengqi.arch@bytedance.com>,
	david@kernel.org, osalvador@suse.de, akpm@linux-foundation.org,
	azpijr@gmail.com
Subject: Re: [PATCH v2 4/5] mm: hugetlb: avoid recursive CMA allocation during migration
Date: Fri, 23 Oct 2026 15:02:35 +0800	[thread overview]
Message-ID: <6e6986a0-b5b4-4ca2-b230-63088f30704f@linux.dev> (raw)
In-Reply-To: <35120f1e65b135ebc7885a85bb39baab90882820.1792651104.git.zhengqi.arch@bytedance.com>



On 2026/10/22 15:31, Qi Zheng wrote:
> From: Qi Zheng <zhengqi.arch@bytedance.com>
>
> Contiguous allocation can migrate allocated HugeTLB folios or replace free
> HugeTLB folios while holding a CMA allocation mutex. Allocating a
> replacement through CMA would recurse into that allocation path once
> non-gigantic HugeTLB pages can use CMA.
>
> Pass allow_cma through the migration and fresh allocation helpers, and
> disable it for MR_CONTIG_RANGE and free folio replacement. Move the CMA
> attempt into the common allocation path, retaining the gigantic size
> restriction. Honor hugetlb_cma_only even when allow_cma is false.
>
> The existing gigantic migration restriction is unchanged.
>
> Assisted-by: LLM
> Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
> ---
>   include/linux/hugetlb.h |  4 +--
>   mm/hugetlb.c            | 69 +++++++++++++++++++++--------------------
>   mm/mempolicy.c          |  2 +-
>   mm/migrate.c            |  3 +-
>   4 files changed, 40 insertions(+), 38 deletions(-)
>
> diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
> index 5029c72418631..38612f7b3478f 100644
> --- a/include/linux/hugetlb.h
> +++ b/include/linux/hugetlb.h
> @@ -736,7 +736,7 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
>   				unsigned long addr, bool cow_from_owner);
>   struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid,
>   				nodemask_t *nmask, gfp_t gfp_mask,
> -				bool allow_alloc_fallback);
> +				bool allow_alloc_fallback, bool allow_cma);
>   struct folio *alloc_hugetlb_folio_reserve(struct hstate *h, int preferred_nid,
>   					  nodemask_t *nmask, gfp_t gfp_mask);
>   
> @@ -1172,7 +1172,7 @@ alloc_hugetlb_folio_reserve(struct hstate *h, int preferred_nid,
>   static inline struct folio *
>   alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid,
>   			nodemask_t *nmask, gfp_t gfp_mask,
> -			bool allow_alloc_fallback)
> +			bool allow_alloc_fallback, bool allow_cma)
>   {
>   	return NULL;
>   }
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 6b08074d11f52..c1a8d00be11ac 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1362,18 +1362,8 @@ static struct folio *dequeue_hugetlb_folio(struct hstate *h, gfp_t gfp_mask,
>   static struct folio *alloc_gigantic_frozen_folio(int order, gfp_t gfp_mask,
>   		int nid, nodemask_t *nodemask)
>   {
> -	struct folio *folio;
> -
> -	folio = hugetlb_cma_alloc_frozen_folio(order, gfp_mask, nid, nodemask);
> -	if (folio)
> -		return folio;
> -
> -	if (hugetlb_cma_exclusive_alloc(order))
> -		return NULL;
> -
> -	folio = (struct folio *)alloc_contig_frozen_pages(1 << order, gfp_mask,
> -							  nid, nodemask);
> -	return folio;
> +	return (struct folio *)alloc_contig_frozen_pages(1 << order, gfp_mask,
> +							 nid, nodemask);
>   }
>   #else /* !CONFIG_ARCH_HAS_GIGANTIC_PAGE || !CONFIG_CONTIG_ALLOC */
>   static struct folio *alloc_gigantic_frozen_folio(int order, gfp_t gfp_mask, int nid,
> @@ -1841,37 +1831,47 @@ static struct folio *alloc_buddy_frozen_folio(int order, gfp_t gfp_mask,
>   
>   static struct folio *only_alloc_fresh_hugetlb_folio(struct hstate *h,
>   		gfp_t gfp_mask, int nid, nodemask_t *nmask,
> -		nodemask_t *node_alloc_noretry)
> +		nodemask_t *node_alloc_noretry, bool allow_cma)
>   {
> -	struct folio *folio;
> +	struct folio *folio = NULL;
>   	int order = huge_page_order(h);
>   
>   	if (nid == NUMA_NO_NODE)
>   		nid = numa_mem_id();
>   
> -	if (order_is_gigantic(order))
> -		folio = alloc_gigantic_frozen_folio(order, gfp_mask, nid, nmask);
> -	else
> -		folio = alloc_buddy_frozen_folio(order, gfp_mask, nid, nmask,
> -						 node_alloc_noretry);
> +	if (allow_cma && order_is_gigantic(order))
> +		folio = hugetlb_cma_alloc_frozen_folio(order, gfp_mask, nid, nmask);
> +	if (!folio) {
> +		if (hugetlb_cma_exclusive_alloc(order))
> +			return NULL;
> +
> +		if (order_is_gigantic(order))
> +			folio = alloc_gigantic_frozen_folio(order, gfp_mask, nid, nmask);
> +		else
> +			folio = alloc_buddy_frozen_folio(order, gfp_mask, nid, nmask,
> +							 node_alloc_noretry);
> +	}
> +
>   	if (folio)
>   		init_new_hugetlb_folio(folio);
> +
>   	return folio;
>   }
>   
>   /*
> - * Common helper to allocate a fresh hugetlb folio. All specific allocators
> - * should use this function to get new hugetlb folio
> + * Common helper to allocate a fresh hugetlb folio. All special allocators
> + * should use this function to get new hugetlb folio.
>    *
>    * Note that returned folio is 'frozen':  ref count of head page and all tail
>    * pages is zero, and the accounting must be done in the caller.
>    */
>   static struct folio *alloc_fresh_hugetlb_folio(struct hstate *h,
> -		gfp_t gfp_mask, int nid, nodemask_t *nmask)
> +		gfp_t gfp_mask, int nid, nodemask_t *nmask, bool allow_cma)
>   {
>   	struct folio *folio;
>   
> -	folio = only_alloc_fresh_hugetlb_folio(h, gfp_mask, nid, nmask, NULL);
> +	folio = only_alloc_fresh_hugetlb_folio(h, gfp_mask, nid, nmask, NULL,
> +					       allow_cma);
>   	if (folio)
>   		hugetlb_vmemmap_optimize_folio(h, folio);
>   	return folio;
> @@ -1911,7 +1911,7 @@ static struct folio *alloc_pool_huge_folio(struct hstate *h,
>   		struct folio *folio;
>   
>   		folio = only_alloc_fresh_hugetlb_folio(h, gfp_mask, node,
> -					nodes_allowed, node_alloc_noretry);
> +					nodes_allowed, node_alloc_noretry, true);
>   		if (folio)
>   			return folio;
>   	}
> @@ -2103,7 +2103,7 @@ static struct folio *alloc_surplus_hugetlb_folio(struct hstate *h,
>   		goto out_unlock;
>   	spin_unlock_irq(&hugetlb_lock);
>   
> -	folio = alloc_fresh_hugetlb_folio(h, gfp_mask, nid, nmask);
> +	folio = alloc_fresh_hugetlb_folio(h, gfp_mask, nid, nmask, true);
>   	if (!folio)
>   		return NULL;
>   
> @@ -2139,14 +2139,14 @@ static struct folio *alloc_surplus_hugetlb_folio(struct hstate *h,
>   }
>   
>   static struct folio *alloc_migrate_hugetlb_folio(struct hstate *h, gfp_t gfp_mask,
> -				     int nid, nodemask_t *nmask)
> +				     int nid, nodemask_t *nmask, bool allow_cma)
>   {
>   	struct folio *folio;
>   
>   	if (hstate_is_gigantic(h))
>   		return NULL;
>   
> -	folio = alloc_fresh_hugetlb_folio(h, gfp_mask, nid, nmask);
> +	folio = alloc_fresh_hugetlb_folio(h, gfp_mask, nid, nmask, allow_cma);
>   	if (!folio)
>   		return NULL;
>   
> @@ -2219,7 +2219,8 @@ struct folio *alloc_hugetlb_folio_reserve(struct hstate *h, int preferred_nid,
>   
>   /* folio migration callback function */
>   struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid,
> -		nodemask_t *nmask, gfp_t gfp_mask, bool allow_alloc_fallback)
> +		nodemask_t *nmask, gfp_t gfp_mask, bool allow_alloc_fallback,

alloc_hugetlb_folio_nodemask() now ends with two adjacent boolean
arguments.

Call sites such as "false, true" are difficult to understand without
looking up the prototype.

Could you please add a comment at the caller to document this?

Thanks,
Muchun

  parent reply	other threads:[~2026-10-23  7:02 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-22  7:31 [PATCH v2 0/5] mm: hugetlb: add CMA support for PMD-sized pages Qi Zheng
2026-10-22  7:31 ` [PATCH v2 1/5] mm: hugetlb: add explicit page size to hugetlb_cma Qi Zheng
2026-10-22  9:50   ` Muchun Song
2026-10-22  7:31 ` [PATCH v2 2/5] mm: hugetlb: group CMA pool and reservation state Qi Zheng
2026-10-22  9:57   ` Muchun Song
2026-10-22  7:31 ` [PATCH v2 3/5] mm: hugetlb: track CMA reservations by pool Qi Zheng
2026-10-22  8:38   ` Jose A. Perez de Azpillaga
2026-10-22 11:21   ` Muchun Song
2026-10-23  6:35     ` Qi Zheng
2026-10-23  6:37       ` Muchun Song
2026-10-22  7:31 ` [PATCH v2 4/5] mm: hugetlb: avoid recursive CMA allocation during migration Qi Zheng
2026-10-22  8:51   ` Jose A. Perez de Azpillaga
2026-10-23  7:02   ` Muchun Song [this message]
2026-10-23  7:21     ` Qi Zheng
2026-10-22  7:31 ` [PATCH v2 5/5] mm: hugetlb: enable CMA allocation for PMD-sized pages Qi Zheng
2026-10-22  9:05   ` Jose A. Perez de Azpillaga
2026-10-22  9:38     ` Qi Zheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6e6986a0-b5b4-4ca2-b230-63088f30704f@linux.dev \
    --to=muchun.song@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=azpijr@gmail.com \
    --cc=david@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=osalvador@suse.de \
    --cc=qi.zheng@linux.dev \
    --cc=zhengqi.arch@bytedance.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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®