* [PATCH v5 0/3] Consolidate memory policy interpretation in alloc_hugetlb_folio()
@ 2026-08-03 13:37 Ackerley Tng via B4 Relay
2026-08-03 13:37 ` [PATCH v5 1/3] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio() Ackerley Tng via B4 Relay
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-08-03 13:37 UTC (permalink / raw)
To: Alistair Popple, Andrew Morton, Byungchul Park,
David Hildenbrand, Gregory Price, Joshua Hahn, Matthew Brost,
Muchun Song, Oscar Salvador, Rakie Kim, Ying Huang, Zi Yan,
erdemaktas, fvdl, jiaqiyan, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Jason Gunthorpe
Cc: linux-kernel, linux-mm, Ackerley Tng
This patch series is the first 3 patches, split out from "Open HugeTLB
allocation routine for more generic use" [1].
I'm splitting these 3 patches into this separate series, and continuing as
v5 from [1] to avoid being blocked on addressing pre-existing
bugs. (Sashiko's reviews on [1] revealed quite a few pre-existing bugs,
which is separately being addressed in [2].)
These 3 patches have been reviewed and can be merged first. (Thank you
Andrew!) The other 3 patches in [1] will probably build on [2], so I'd like
to leave those to later.
In this v5, the only change is to the first patch - I improved the wording
of the comment just above the call to dequeue_hugetlb_folio_vma() in
alloc_hugetlb_folio().
[1] https://lore.kernel.org/all/20260702-hugetlb-open-up-v4-0-d53cefcccf34@google.com/T/
[2] https://lore.kernel.org/all/20260722-hugetlb-alloc-failure-fixes-v4-0-88e8b81970dc@google.com/T/
Testing:
+ libhugetlbfs tests pass
+ tools/testing/selftests/mm/ksft_hugetlb.sh passes
RFC v1: https://lore.kernel.org/all/bb35a69a-5be9-45f5-a557-1902487a1bc2@linux.dev/
v2: https://lore.kernel.org/r/20260506-hugetlb-open-up-v2-0-826a0c5f28fc@google.com
v3: https://lore.kernel.org/r/20260518-hugetlb-open-up-v3-0-e14b302477f8@google.com
v4: https://lore.kernel.org/r/20260702-hugetlb-open-up-v4-0-d53cefcccf34@google.com
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
Ackerley Tng (3):
mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio()
mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol()
mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma()
include/uapi/linux/mempolicy.h | 2 +-
mm/hugetlb.c | 110 +++++++++++++++++++++++------------------
2 files changed, 62 insertions(+), 50 deletions(-)
---
base-commit: 075b74841bd0065a3bda3440873c747938e69b68
change-id: 20260803-hugetlb-mpol-interpretation-1c61e03073b4
Best regards,
--
Ackerley Tng <ackerleytng@google.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 1/3] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio()
2026-08-03 13:37 [PATCH v5 0/3] Consolidate memory policy interpretation in alloc_hugetlb_folio() Ackerley Tng via B4 Relay
@ 2026-08-03 13:37 ` Ackerley Tng via B4 Relay
2026-08-03 14:49 ` Gregory Price
2026-08-03 13:37 ` [PATCH v5 2/3] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol() Ackerley Tng via B4 Relay
2026-08-03 13:38 ` [PATCH v5 3/3] mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma() Ackerley Tng via B4 Relay
2 siblings, 1 reply; 7+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-08-03 13:37 UTC (permalink / raw)
To: Alistair Popple, Andrew Morton, Byungchul Park,
David Hildenbrand, Gregory Price, Joshua Hahn, Matthew Brost,
Muchun Song, Oscar Salvador, Rakie Kim, Ying Huang, Zi Yan,
erdemaktas, fvdl, jiaqiyan, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Jason Gunthorpe
Cc: linux-kernel, linux-mm, Ackerley Tng
From: Ackerley Tng <ackerleytng@google.com>
The dequeue_hugetlb_folio_vma() function currently handles the gbl_chg
parameter to determine if a folio can be dequeued based on global page
availability. This leaks reservation-specific logic into the dequeueing
path.
Relocate this logic to alloc_hugetlb_folio() so that
dequeue_hugetlb_folio_vma() focuses solely on selecting and dequeuing a
folio. In alloc_hugetlb_folio(), only attempt to dequeue a folio if a
reservation exists (gbl_chg == 0) or if there are available huge pages in
the global pool.
No functional change intended.
Reviewed-by: James Houghton <jthoughton@google.com>
Acked-by: Oscar Salvador <osalvador@suse.de>
Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com>
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
mm/hugetlb.c | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index e93c4d2456aa4..7985cfd21a03c 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1319,7 +1319,7 @@ static unsigned long available_huge_pages(struct hstate *h)
static struct folio *dequeue_hugetlb_folio_vma(struct hstate *h,
struct vm_area_struct *vma,
- unsigned long address, long gbl_chg)
+ unsigned long address)
{
struct folio *folio = NULL;
struct mempolicy *mpol;
@@ -1327,13 +1327,6 @@ static struct folio *dequeue_hugetlb_folio_vma(struct hstate *h,
nodemask_t *nodemask;
int nid;
- /*
- * gbl_chg==1 means the allocation requires a new page that was not
- * reserved before. Making sure there's at least one free page.
- */
- if (gbl_chg && !available_huge_pages(h))
- goto err;
-
gfp_mask = htlb_alloc_mask(h);
nid = huge_node(vma, address, gfp_mask, &mpol, &nodemask);
@@ -1351,9 +1344,6 @@ static struct folio *dequeue_hugetlb_folio_vma(struct hstate *h,
mpol_cond_put(mpol);
return folio;
-
-err:
- return NULL;
}
#if defined(CONFIG_ARCH_HAS_GIGANTIC_PAGE) && defined(CONFIG_CONTIG_ALLOC)
@@ -2923,12 +2913,18 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
goto out_uncharge_cgroup_reservation;
spin_lock_irq(&hugetlb_lock);
+
/*
- * glb_chg is passed to indicate whether or not a page must be taken
- * from the global free pool (global change). gbl_chg == 0 indicates
- * a reservation exists for the allocation.
+ * Try to dequeue from the pool if either:
+ * 1) A reservation exists (gbl_chg == 0).
+ * 2) No reservation exists, but there are unreserved (available)
+ * pages in the pool; this prefers using pre-allocated pool
+ * pages over allocating fresh ones from the buddy allocator.
*/
- folio = dequeue_hugetlb_folio_vma(h, vma, addr, gbl_chg);
+ folio = NULL;
+ if (!gbl_chg || available_huge_pages(h))
+ folio = dequeue_hugetlb_folio_vma(h, vma, addr);
+
if (!folio) {
spin_unlock_irq(&hugetlb_lock);
folio = alloc_buddy_hugetlb_folio_with_mpol(h, vma, addr);
--
2.55.0.508.g3f0d502094-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 2/3] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol()
2026-08-03 13:37 [PATCH v5 0/3] Consolidate memory policy interpretation in alloc_hugetlb_folio() Ackerley Tng via B4 Relay
2026-08-03 13:37 ` [PATCH v5 1/3] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio() Ackerley Tng via B4 Relay
@ 2026-08-03 13:37 ` Ackerley Tng via B4 Relay
2026-08-03 14:55 ` Gregory Price
2026-08-03 13:38 ` [PATCH v5 3/3] mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma() Ackerley Tng via B4 Relay
2 siblings, 1 reply; 7+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-08-03 13:37 UTC (permalink / raw)
To: Alistair Popple, Andrew Morton, Byungchul Park,
David Hildenbrand, Gregory Price, Joshua Hahn, Matthew Brost,
Muchun Song, Oscar Salvador, Rakie Kim, Ying Huang, Zi Yan,
erdemaktas, fvdl, jiaqiyan, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Jason Gunthorpe
Cc: linux-kernel, linux-mm, Ackerley Tng
From: Ackerley Tng <ackerleytng@google.com>
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@google.com>
Acked-by: Oscar Salvador <osalvador@suse.de>
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
include/uapi/linux/mempolicy.h | 2 +-
mm/hugetlb.c | 54 ++++++++++++++++++++++++++++--------------
2 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/include/uapi/linux/mempolicy.h b/include/uapi/linux/mempolicy.h
index 6c962d866e864..7f6fc9599693b 100644
--- a/include/uapi/linux/mempolicy.h
+++ b/include/uapi/linux/mempolicy.h
@@ -16,7 +16,7 @@
*/
/* Policies */
-enum {
+enum mempolicy_mode {
MPOL_DEFAULT,
MPOL_PREFERRED,
MPOL_BIND,
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 7985cfd21a03c..3a159de08a0b6 100644
--- 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;
+ enum mempolicy_mode mode;
+};
+
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;
}
-/*
- * Use the VMA's mpolicy to allocate a huge page from the buddy.
- */
static
-struct folio *alloc_buddy_hugetlb_folio_with_mpol(struct hstate *h,
- struct vm_area_struct *vma, unsigned long addr)
+struct folio *alloc_buddy_hugetlb_folio(struct hstate *h,
+ gfp_t gfp_mask, struct mempolicy_interpreted *mpoli)
{
struct folio *folio = NULL;
- struct mempolicy *mpol;
- gfp_t gfp_mask = htlb_alloc_mask(h);
- int nid;
- nodemask_t *nodemask;
+ nodemask_t *nodemask = mpoli->nodemask;
- nid = huge_node(vma, addr, gfp_mask, &mpol, &nodemask);
- if (mpol_is_preferred_many(mpol)) {
+ if (mpoli->mode == MPOL_PREFERRED_MANY) {
gfp_t gfp = gfp_mask & ~(__GFP_DIRECT_RECLAIM | __GFP_NOFAIL);
- folio = alloc_surplus_hugetlb_folio(h, gfp, nid, nodemask);
+ folio = alloc_surplus_hugetlb_folio(h, gfp, mpoli->nid,
+ nodemask);
/* Fallback to all nodes if page==NULL */
nodemask = NULL;
}
- if (!folio)
- folio = alloc_surplus_hugetlb_folio(h, gfp_mask, nid, nodemask);
- mpol_cond_put(mpol);
+ if (!folio) {
+ folio = alloc_surplus_hugetlb_folio(h, gfp_mask, mpoli->nid,
+ nodemask);
+ }
+
return folio;
}
@@ -2853,7 +2855,7 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
int ret, idx;
struct hugetlb_cgroup *h_cg = NULL;
struct hugetlb_cgroup *h_cg_rsvd = NULL;
- gfp_t gfp = htlb_alloc_mask(h) | __GFP_RETRY_MAYFAIL;
+ gfp_t gfp = htlb_alloc_mask(h);
idx = hstate_index(h);
@@ -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
+ .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);
@@ -2983,7 +3001,7 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
}
}
- ret = mem_cgroup_charge_hugetlb(folio, gfp);
+ ret = mem_cgroup_charge_hugetlb(folio, gfp | __GFP_RETRY_MAYFAIL);
/*
* Unconditionally increment NR_HUGETLB here. If it turns out that
* mem_cgroup_charge_hugetlb failed, then immediately free the page and
--
2.55.0.508.g3f0d502094-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 3/3] mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma()
2026-08-03 13:37 [PATCH v5 0/3] Consolidate memory policy interpretation in alloc_hugetlb_folio() Ackerley Tng via B4 Relay
2026-08-03 13:37 ` [PATCH v5 1/3] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio() Ackerley Tng via B4 Relay
2026-08-03 13:37 ` [PATCH v5 2/3] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol() Ackerley Tng via B4 Relay
@ 2026-08-03 13:38 ` Ackerley Tng via B4 Relay
2026-08-03 14:59 ` Gregory Price
2 siblings, 1 reply; 7+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-08-03 13:38 UTC (permalink / raw)
To: Alistair Popple, Andrew Morton, Byungchul Park,
David Hildenbrand, Gregory Price, Joshua Hahn, Matthew Brost,
Muchun Song, Oscar Salvador, Rakie Kim, Ying Huang, Zi Yan,
erdemaktas, fvdl, jiaqiyan, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Jason Gunthorpe
Cc: linux-kernel, linux-mm, Ackerley Tng
From: Ackerley Tng <ackerleytng@google.com>
Move memory policy interpretation out of dequeue_hugetlb_folio_vma() and
into alloc_hugetlb_folio() to separate reading and interpretation of memory
policy from actual allocation.
Also rename dequeue_hugetlb_folio_vma() to
dequeue_hugetlb_folio_with_mpol() to remove association with vma and to
align with alloc_buddy_hugetlb_folio_with_mpol().
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.
No functional change intended.
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
Reviewed-by: James Houghton <jthoughton@google.com>
---
mm/hugetlb.c | 66 +++++++++++++++++++++++++++++-------------------------------
1 file changed, 32 insertions(+), 34 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 3a159de08a0b6..a11cb919e00fe 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1323,32 +1323,26 @@ struct mempolicy_interpreted {
enum mempolicy_mode mode;
};
-static struct folio *dequeue_hugetlb_folio_vma(struct hstate *h,
- struct vm_area_struct *vma,
- unsigned long address)
+static struct folio *dequeue_hugetlb_folio(struct hstate *h, gfp_t gfp_mask,
+ struct mempolicy_interpreted *mpoli)
{
+ nodemask_t *nodemask = mpoli->nodemask;
struct folio *folio = NULL;
- struct mempolicy *mpol;
- gfp_t gfp_mask;
- nodemask_t *nodemask;
- int nid;
-
- gfp_mask = htlb_alloc_mask(h);
- nid = huge_node(vma, address, gfp_mask, &mpol, &nodemask);
- if (mpol_is_preferred_many(mpol)) {
+ if (mpoli->mode == MPOL_PREFERRED_MANY) {
folio = dequeue_hugetlb_folio_nodemask(h, gfp_mask,
- nid, nodemask);
+ mpoli->nid,
+ nodemask);
/* Fallback to all nodes if page==NULL */
nodemask = NULL;
}
- if (!folio)
+ if (!folio) {
folio = dequeue_hugetlb_folio_nodemask(h, gfp_mask,
- nid, nodemask);
-
- mpol_cond_put(mpol);
+ mpoli->nid,
+ nodemask);
+ }
return folio;
}
@@ -2855,7 +2849,11 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
int ret, idx;
struct hugetlb_cgroup *h_cg = NULL;
struct hugetlb_cgroup *h_cg_rsvd = NULL;
+ struct mempolicy_interpreted mpoli;
gfp_t gfp = htlb_alloc_mask(h);
+ struct mempolicy *mpol;
+ nodemask_t *nodemask;
+ int nid;
idx = hstate_index(h);
@@ -2914,6 +2912,18 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
if (ret)
goto out_uncharge_cgroup_reservation;
+ /* Takes reference on mpol. */
+ 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
+ .nodemask = nodemask,
+ };
+
spin_lock_irq(&hugetlb_lock);
/*
@@ -2925,35 +2935,23 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
*/
folio = NULL;
if (!gbl_chg || available_huge_pages(h))
- folio = dequeue_hugetlb_folio_vma(h, vma, addr);
+ folio = dequeue_hugetlb_folio(h, gfp, &mpoli);
if (!folio) {
- struct mempolicy_interpreted mpoli;
- struct mempolicy *mpol;
- nodemask_t *nodemask;
- int nid;
-
spin_unlock_irq(&hugetlb_lock);
- 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
- .nodemask = nodemask,
- };
folio = alloc_buddy_hugetlb_folio(h, gfp, &mpoli);
- mpol_cond_put(mpol);
- if (!folio)
+ if (!folio) {
+ mpol_cond_put(mpol);
goto out_uncharge_cgroup;
+ }
spin_lock_irq(&hugetlb_lock);
list_add(&folio->lru, &h->hugepage_activelist);
folio_ref_unfreeze(folio, 1);
/* Fall through */
}
+ mpol_cond_put(mpol);
+
/*
* Either dequeued or buddy-allocated folio needs to add special
* mark to the folio when it consumes a global reservation.
--
2.55.0.508.g3f0d502094-goog
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 1/3] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio()
2026-08-03 13:37 ` [PATCH v5 1/3] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio() Ackerley Tng via B4 Relay
@ 2026-08-03 14:49 ` Gregory Price
0 siblings, 0 replies; 7+ messages in thread
From: Gregory Price @ 2026-08-03 14:49 UTC (permalink / raw)
To: Ackerley Tng
Cc: Alistair Popple, Andrew Morton, Byungchul Park,
David Hildenbrand, Joshua Hahn, Matthew Brost, Muchun Song,
Oscar Salvador, Rakie Kim, Ying Huang, Zi Yan, erdemaktas, fvdl,
jiaqiyan, jthoughton, mhocko, michael.roth, pasha.tatashin,
pbonzini, peterx, pratyush, rick.p.edgecombe, rientjes,
roman.gushchin, seanjc, shakeel.butt, shivankg, vannapurve,
yan.y.zhao, Jason Gunthorpe, linux-kernel, linux-mm
On Mon, Aug 03, 2026 at 06:37:58AM -0700, Ackerley Tng wrote:
> The dequeue_hugetlb_folio_vma() function currently handles the gbl_chg
> parameter to determine if a folio can be dequeued based on global page
> availability. This leaks reservation-specific logic into the dequeueing
> path.
>
> Relocate this logic to alloc_hugetlb_folio() so that
> dequeue_hugetlb_folio_vma() focuses solely on selecting and dequeuing a
> folio. In alloc_hugetlb_folio(), only attempt to dequeue a folio if a
> reservation exists (gbl_chg == 0) or if there are available huge pages in
> the global pool.
>
> No functional change intended.
>
> Reviewed-by: James Houghton <jthoughton@google.com>
> Acked-by: Oscar Salvador <osalvador@suse.de>
> Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com>
> Signed-off-by: Ackerley Tng <ackerleytng@google.com>
Reviewed-by: Gregory Price <gourry@gourry.net>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 2/3] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol()
2026-08-03 13:37 ` [PATCH v5 2/3] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol() Ackerley Tng via B4 Relay
@ 2026-08-03 14:55 ` Gregory Price
0 siblings, 0 replies; 7+ messages in thread
From: Gregory Price @ 2026-08-03 14:55 UTC (permalink / raw)
To: Ackerley Tng
Cc: Alistair Popple, Andrew Morton, Byungchul Park,
David Hildenbrand, Joshua Hahn, Matthew Brost, Muchun Song,
Oscar Salvador, Rakie Kim, Ying Huang, Zi Yan, erdemaktas, fvdl,
jiaqiyan, jthoughton, mhocko, michael.roth, pasha.tatashin,
pbonzini, peterx, pratyush, rick.p.edgecombe, rientjes,
roman.gushchin, seanjc, shakeel.butt, shivankg, vannapurve,
yan.y.zhao, Jason Gunthorpe, linux-kernel, linux-mm
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@google.com>
> Acked-by: Oscar Salvador <osalvador@suse.de>
> Signed-off-by: Ackerley Tng <ackerleytng@google.com>
> ---
> 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);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 3/3] mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma()
2026-08-03 13:38 ` [PATCH v5 3/3] mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma() Ackerley Tng via B4 Relay
@ 2026-08-03 14:59 ` Gregory Price
0 siblings, 0 replies; 7+ messages in thread
From: Gregory Price @ 2026-08-03 14:59 UTC (permalink / raw)
To: Ackerley Tng
Cc: Alistair Popple, Andrew Morton, Byungchul Park,
David Hildenbrand, Joshua Hahn, Matthew Brost, Muchun Song,
Oscar Salvador, Rakie Kim, Ying Huang, Zi Yan, erdemaktas, fvdl,
jiaqiyan, jthoughton, mhocko, michael.roth, pasha.tatashin,
pbonzini, peterx, pratyush, rick.p.edgecombe, rientjes,
roman.gushchin, seanjc, shakeel.butt, shivankg, vannapurve,
yan.y.zhao, Jason Gunthorpe, linux-kernel, linux-mm
On Mon, Aug 03, 2026 at 06:38:00AM -0700, Ackerley Tng wrote:
... snip ...
> @@ -2925,35 +2935,23 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
> */
> folio = NULL;
> if (!gbl_chg || available_huge_pages(h))
> - folio = dequeue_hugetlb_folio_vma(h, vma, addr);
> + folio = dequeue_hugetlb_folio(h, gfp, &mpoli);
>
> if (!folio) {
> - struct mempolicy_interpreted mpoli;
> - struct mempolicy *mpol;
> - nodemask_t *nodemask;
> - int nid;
> -
> spin_unlock_irq(&hugetlb_lock);
> - 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
> - .nodemask = nodemask,
> - };
Bah, mea culpa on prior comment, i did not notice this was a prexisting
patterns. This is frustrating to say the least.
It does seem like there should be a better way to do this, but i think
we should be ok with this for now.
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-03 14:59 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-03 13:37 [PATCH v5 0/3] Consolidate memory policy interpretation in alloc_hugetlb_folio() Ackerley Tng via B4 Relay
2026-08-03 13:37 ` [PATCH v5 1/3] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio() Ackerley Tng via B4 Relay
2026-08-03 14:49 ` Gregory Price
2026-08-03 13:37 ` [PATCH v5 2/3] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol() Ackerley Tng via B4 Relay
2026-08-03 14:55 ` Gregory Price
2026-08-03 13:38 ` [PATCH v5 3/3] mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma() Ackerley Tng via B4 Relay
2026-08-03 14:59 ` Gregory Price
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®