Re: [PATCH v5 2/3] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol()
From: Gregory Price
Date: Mon Aug 03 2026 - 11:53:36 EST
On Mon, Aug 03, 2026 at 06:37:59AM -0700, Ackerley Tng wrote:
> Move memory policy interpretation out of
> alloc_buddy_hugetlb_folio_with_mpol() and into alloc_hugetlb_folio() to
> separate reading and interpretation of memory policy from actual
> allocation.
>
> This will later allow memory policy to be interpreted outside of the
> process of allocating a hugetlb folio entirely. This opens doors for other
> callers of the HugeTLB folio allocation function, such as guest_memfd,
> where memory may not always be mapped and hence may not have an associated
> vma.
>
> Introduce struct mempolicy_interpreted to hold all the components of an
> interpreted memory policy.
>
> Rename alloc_buddy_hugetlb_folio_with_mpol() to alloc_buddy_hugetlb_folio()
> since the function no longer interprets memory policy.
>
> No functional change intended.
>
> Reviewed-by: James Houghton <jthoughton@xxxxxxxxxx>
> Acked-by: Oscar Salvador <osalvador@xxxxxxx>
> Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
> ---
> include/uapi/linux/mempolicy.h | 2 +-
> mm/hugetlb.c | 54 ++++++++++++++++++++++++++++--------------
> 2 files changed, 37 insertions(+), 19 deletions(-)
>
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1317,6 +1317,12 @@ static unsigned long available_huge_pages(struct hstate *h)
> return h->free_huge_pages - h->resv_huge_pages;
> }
>
> +struct mempolicy_interpreted {
> + int nid;
> + nodemask_t *nodemask;
^^ const please (mempolicy owns it, it should never change)
> + enum mempolicy_mode mode;
> +};
> +
Is this intended to be an ephemeral struct that will eventually be
removed? Because it feels like mempolicy.c should just be handling this
directly instead of needing this cached structure.
> static struct folio *dequeue_hugetlb_folio_vma(struct hstate *h,
> struct vm_area_struct *vma,
> unsigned long address)
> @@ -2138,32 +2144,28 @@ static struct folio *alloc_migrate_hugetlb_folio(struct hstate *h, gfp_t gfp_mas
> return folio;
> }
>
... snip ...
> @@ -2926,8 +2928,24 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
> folio = dequeue_hugetlb_folio_vma(h, vma, addr);
>
> if (!folio) {
> + struct mempolicy_interpreted mpoli;
> + struct mempolicy *mpol;
> + nodemask_t *nodemask;
> + int nid;
> +
> spin_unlock_irq(&hugetlb_lock);
> - folio = alloc_buddy_hugetlb_folio_with_mpol(h, vma, addr);
> + nid = huge_node(vma, addr, gfp, &mpol, &nodemask);
> + mpoli = (struct mempolicy_interpreted){
> + .nid = nid,
> +#ifdef CONFIG_NUMA
> + .mode = mpol ? mpol->mode : MPOL_DEFAULT,
> +#else
> + .mode = MPOL_DEFAULT,
> +#endif
This is not great, and tells me this interaction should probably
be sunk into mempolicy instead of pulling ifdef/else into hugetlb.
> + .nodemask = nodemask,
> + };
> + folio = alloc_buddy_hugetlb_folio(h, gfp, &mpoli);
> + mpol_cond_put(mpol);
> if (!folio)
> goto out_uncharge_cgroup;
> spin_lock_irq(&hugetlb_lock);