* [PATCH v4 1/6] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio()
2026-07-02 16:21 [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Ackerley Tng via B4 Relay
@ 2026-07-02 16:21 ` Ackerley Tng via B4 Relay
2026-07-02 16:21 ` [PATCH v4 2/6] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol() Ackerley Tng via B4 Relay
` (6 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-07-02 16:21 UTC (permalink / raw)
To: Muchun Song, Oscar Salvador, David Hildenbrand, Andrew Morton,
fvdl, jiaqiyan, joshua.hahnjy, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Zi Yan, Matthew Brost, Rakie Kim,
Byungchul Park, Gregory Price, Ying Huang, Alistair Popple,
Dan Williams, Jason Gunthorpe
Cc: linux-mm, linux-kernel, 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 | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 571212b80835e..83ab9390db565 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,17 @@ 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.
+ * gbl_chg == 0 indicates a reservation exists for the
+ * allocation, so try dequeuing a page. In case there was no
+ * reservation, try dequeuing a page if there are available
+ * pages in the global pool.
*/
- 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.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v4 2/6] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol()
2026-07-02 16:21 [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Ackerley Tng via B4 Relay
2026-07-02 16:21 ` [PATCH v4 1/6] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio() Ackerley Tng via B4 Relay
@ 2026-07-02 16:21 ` Ackerley Tng via B4 Relay
2026-07-02 16:21 ` [PATCH v4 3/6] mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma() Ackerley Tng via B4 Relay
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-07-02 16:21 UTC (permalink / raw)
To: Muchun Song, Oscar Salvador, David Hildenbrand, Andrew Morton,
fvdl, jiaqiyan, joshua.hahnjy, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Zi Yan, Matthew Brost, Rakie Kim,
Byungchul Park, Gregory Price, Ying Huang, Alistair Popple,
Dan Williams, Jason Gunthorpe
Cc: linux-mm, linux-kernel, 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 83ab9390db565..cdcfff521b6db 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);
@@ -2925,8 +2927,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);
@@ -2982,7 +3000,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.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v4 3/6] mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma()
2026-07-02 16:21 [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Ackerley Tng via B4 Relay
2026-07-02 16:21 ` [PATCH v4 1/6] mm: hugetlb: Consolidate interpretation of gbl_chg within alloc_hugetlb_folio() Ackerley Tng via B4 Relay
2026-07-02 16:21 ` [PATCH v4 2/6] mm: hugetlb: Move mpol interpretation out of alloc_buddy_hugetlb_folio_with_mpol() Ackerley Tng via B4 Relay
@ 2026-07-02 16:21 ` Ackerley Tng via B4 Relay
2026-07-02 16:21 ` [PATCH v4 4/6] mm: hugetlb: Use error variable in alloc_hugetlb_folio Ackerley Tng via B4 Relay
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-07-02 16:21 UTC (permalink / raw)
To: Muchun Song, Oscar Salvador, David Hildenbrand, Andrew Morton,
fvdl, jiaqiyan, joshua.hahnjy, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Zi Yan, Matthew Brost, Rakie Kim,
Byungchul Park, Gregory Price, Ying Huang, Alistair Popple,
Dan Williams, Jason Gunthorpe
Cc: linux-mm, linux-kernel, 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 cdcfff521b6db..f595ab15f9fcb 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);
/*
@@ -2924,35 +2934,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.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v4 4/6] mm: hugetlb: Use error variable in alloc_hugetlb_folio
2026-07-02 16:21 [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Ackerley Tng via B4 Relay
` (2 preceding siblings ...)
2026-07-02 16:21 ` [PATCH v4 3/6] mm: hugetlb: Move mpol interpretation out of dequeue_hugetlb_folio_vma() Ackerley Tng via B4 Relay
@ 2026-07-02 16:21 ` Ackerley Tng via B4 Relay
2026-07-02 16:21 ` [PATCH v4 5/6] mm: hugetlb: Move mem_cgroup_charge_hugetlb() earlier in allocation Ackerley Tng via B4 Relay
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-07-02 16:21 UTC (permalink / raw)
To: Muchun Song, Oscar Salvador, David Hildenbrand, Andrew Morton,
fvdl, jiaqiyan, joshua.hahnjy, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Zi Yan, Matthew Brost, Rakie Kim,
Byungchul Park, Gregory Price, Ying Huang, Alistair Popple,
Dan Williams, Jason Gunthorpe
Cc: linux-mm, linux-kernel, Ackerley Tng
From: Ackerley Tng <ackerleytng@google.com>
Refactor alloc_hugetlb_folio to use a local variable for returning error
codes. Instead of returning ERR_PTR(-ENOSPC) at the end of the error
path, assign -ENOSPC to a return variable at each failure point and
return that variable at the end.
This allows the cleanup goto targets to be used with other errors in a
later patch.
No functional change intended.
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
mm/hugetlb.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index f595ab15f9fcb..176b7e9130a38 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2887,8 +2887,10 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
*/
if (map_chg) {
gbl_chg = hugepage_subpool_get_pages(spool, 1);
- if (gbl_chg < 0)
+ if (gbl_chg < 0) {
+ ret = -ENOSPC;
goto out_end_reservation;
+ }
} else {
/*
* If we have the vma reservation ready, no need for extra
@@ -2904,13 +2906,17 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
if (map_chg) {
ret = hugetlb_cgroup_charge_cgroup_rsvd(
idx, pages_per_huge_page(h), &h_cg_rsvd);
- if (ret)
+ if (ret) {
+ ret = -ENOSPC;
goto out_subpool_put;
+ }
}
ret = hugetlb_cgroup_charge_cgroup(idx, pages_per_huge_page(h), &h_cg);
- if (ret)
+ if (ret) {
+ ret = -ENOSPC;
goto out_uncharge_cgroup_reservation;
+ }
/* Takes reference on mpol. */
nid = huge_node(vma, addr, gfp, &mpol, &nodemask);
@@ -2941,6 +2947,7 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
folio = alloc_buddy_hugetlb_folio(h, gfp, &mpoli);
if (!folio) {
mpol_cond_put(mpol);
+ ret = -ENOSPC;
goto out_uncharge_cgroup;
}
spin_lock_irq(&hugetlb_lock);
@@ -3033,7 +3040,7 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
out_end_reservation:
if (map_chg != MAP_CHG_ENFORCED)
vma_end_reservation(h, vma, addr);
- return ERR_PTR(-ENOSPC);
+ return ERR_PTR(ret);
}
static __init void *alloc_bootmem(struct hstate *h, int nid, bool node_exact)
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v4 5/6] mm: hugetlb: Move mem_cgroup_charge_hugetlb() earlier in allocation
2026-07-02 16:21 [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Ackerley Tng via B4 Relay
` (3 preceding siblings ...)
2026-07-02 16:21 ` [PATCH v4 4/6] mm: hugetlb: Use error variable in alloc_hugetlb_folio Ackerley Tng via B4 Relay
@ 2026-07-02 16:21 ` Ackerley Tng via B4 Relay
2026-07-02 22:03 ` Andrew Morton
2026-07-02 16:21 ` [PATCH v4 6/6] mm: hugetlb: Refactor out hugetlb_alloc_folio() Ackerley Tng via B4 Relay
` (2 subsequent siblings)
7 siblings, 1 reply; 11+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-07-02 16:21 UTC (permalink / raw)
To: Muchun Song, Oscar Salvador, David Hildenbrand, Andrew Morton,
fvdl, jiaqiyan, joshua.hahnjy, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Zi Yan, Matthew Brost, Rakie Kim,
Byungchul Park, Gregory Price, Ying Huang, Alistair Popple,
Dan Williams, Jason Gunthorpe
Cc: linux-mm, linux-kernel, Ackerley Tng
From: Ackerley Tng <ackerleytng@google.com>
Move mem_cgroup_charge_hugetlb() earlier in the folio allocation
process. This change draws a cleaner line between memcg charging and the
subsequent hugetlb-specific reservation logic for VMAs and subpools.
While it would be ideal to make all accounting and reservations perfectly
symmetric, mem_cgroup_charge_hugetlb() is a complex operation that cannot
be performed under the hugetlb_lock. Moving the charge to this earlier
point ensures that memcg charging is handled before the code begins
manipulating subpool and VMA-specific state. These two types of accounting
will be separated in a future patch.
If mem_cgroup_charge_hugetlb() fails, the code now branches to
out_subpool_put to ensure the folio is freed and the subpool references are
handled correctly.
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
mm/hugetlb.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 176b7e9130a38..08ac28111e694 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2978,6 +2978,24 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
spin_unlock_irq(&hugetlb_lock);
+ 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
+ * decrement NR_HUGETLB.
+ */
+ lruvec_stat_mod_folio(folio, NR_HUGETLB, pages_per_huge_page(h));
+
+ if (ret == -ENOMEM) {
+ free_huge_folio(folio);
+ /*
+ * Skip uncharging hugetlb_cgroup since the charges
+ * were committed to the folio and freeing the folio
+ * would have cleared those up.
+ */
+ goto out_subpool_put;
+ }
+
hugetlb_set_folio_subpool(folio, spool);
if (map_chg != MAP_CHG_ENFORCED) {
@@ -3005,19 +3023,6 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
}
}
- 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
- * decrement NR_HUGETLB.
- */
- lruvec_stat_mod_folio(folio, NR_HUGETLB, pages_per_huge_page(h));
-
- if (ret == -ENOMEM) {
- free_huge_folio(folio);
- return ERR_PTR(-ENOMEM);
- }
-
return folio;
out_uncharge_cgroup:
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v4 5/6] mm: hugetlb: Move mem_cgroup_charge_hugetlb() earlier in allocation
2026-07-02 16:21 ` [PATCH v4 5/6] mm: hugetlb: Move mem_cgroup_charge_hugetlb() earlier in allocation Ackerley Tng via B4 Relay
@ 2026-07-02 22:03 ` Andrew Morton
0 siblings, 0 replies; 11+ messages in thread
From: Andrew Morton @ 2026-07-02 22:03 UTC (permalink / raw)
To: ackerleytng
Cc: Ackerley Tng via B4 Relay, Muchun Song, Oscar Salvador,
David Hildenbrand, fvdl, jiaqiyan, joshua.hahnjy, jthoughton,
mhocko, michael.roth, pasha.tatashin, pbonzini, peterx, pratyush,
rick.p.edgecombe, rientjes, roman.gushchin, seanjc, shakeel.butt,
shivankg, vannapurve, yan.y.zhao, Zi Yan, Matthew Brost,
Rakie Kim, Byungchul Park, Gregory Price, Ying Huang,
Alistair Popple, Dan Williams, Jason Gunthorpe, linux-mm,
linux-kernel
On Thu, 02 Jul 2026 09:21:49 -0700 Ackerley Tng via B4 Relay <devnull+ackerleytng.google.com@kernel.org> wrote:
> Move mem_cgroup_charge_hugetlb() earlier in the folio allocation
> process. This change draws a cleaner line between memcg charging and the
> subsequent hugetlb-specific reservation logic for VMAs and subpools.
>
> While it would be ideal to make all accounting and reservations perfectly
> symmetric, mem_cgroup_charge_hugetlb() is a complex operation that cannot
> be performed under the hugetlb_lock. Moving the charge to this earlier
> point ensures that memcg charging is handled before the code begins
> manipulating subpool and VMA-specific state. These two types of accounting
> will be separated in a future patch.
>
> If mem_cgroup_charge_hugetlb() fails, the code now branches to
> out_subpool_put to ensure the folio is freed and the subpool references are
> handled correctly.
Is this patch also "No functional change intended"?
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 6/6] mm: hugetlb: Refactor out hugetlb_alloc_folio()
2026-07-02 16:21 [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Ackerley Tng via B4 Relay
` (4 preceding siblings ...)
2026-07-02 16:21 ` [PATCH v4 5/6] mm: hugetlb: Move mem_cgroup_charge_hugetlb() earlier in allocation Ackerley Tng via B4 Relay
@ 2026-07-02 16:21 ` Ackerley Tng via B4 Relay
2026-07-02 16:51 ` [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Zi Yan
2026-07-02 22:12 ` Andrew Morton
7 siblings, 0 replies; 11+ messages in thread
From: Ackerley Tng via B4 Relay @ 2026-07-02 16:21 UTC (permalink / raw)
To: Muchun Song, Oscar Salvador, David Hildenbrand, Andrew Morton,
fvdl, jiaqiyan, joshua.hahnjy, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Zi Yan, Matthew Brost, Rakie Kim,
Byungchul Park, Gregory Price, Ying Huang, Alistair Popple,
Dan Williams, Jason Gunthorpe
Cc: linux-mm, linux-kernel, Ackerley Tng
From: Ackerley Tng <ackerleytng@google.com>
Refactor out hugetlb_alloc_folio() from alloc_hugetlb_folio(), which
handles allocation of a folio and memory and HugeTLB charging to cgroups.
This refactoring decouples the HugeTLB page allocation from VMAs,
specifically:
1. Reservations (as in resv_map) are stored in the vma
2. mpol is stored at vma->vm_policy
3. A vma must be used for allocation even if the pages are not meant to be
used by host process.
Without this coupling, VMAs are no longer a requirement for
allocation. This opens up the allocation routine for usage without VMAs,
which will allow guest_memfd to use HugeTLB as a more generic allocator of
huge pages, since guest_memfd memory may not have any associated VMAs by
design. In addition, direct allocations from HugeTLB could possibly be
refactored to avoid the use of a pseudo-VMA.
Also, this decouples HugeTLB page allocation from HugeTLBfs, where the
subpool is stored at the fs mount. This is also a requirement for
guest_memfd, where the plan is to have a subpool created per-fd and stored
on the inode.
Provide and use alloc_flags to allow more allocation knobs in future
without expanding the number of parameters in hugetlb_alloc_folio().
No functional change intended.
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
include/linux/hugetlb.h | 18 +++++
mm/hugetlb.c | 206 ++++++++++++++++++++++++++----------------------
2 files changed, 131 insertions(+), 93 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 2abaf99321e90..d506348ae2f0e 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -2,6 +2,7 @@
#ifndef _LINUX_HUGETLB_H
#define _LINUX_HUGETLB_H
+#include <linux/mempolicy.h>
#include <linux/mm.h>
#include <linux/mm_types.h>
#include <linux/mmdebug.h>
@@ -691,6 +692,23 @@ bool hugetlb_bootmem_page_zones_valid(int nid, struct huge_bootmem_page *m);
int isolate_or_dissolve_huge_folio(struct folio *folio, struct list_head *list);
int replace_free_hugepage_folios(unsigned long start_pfn, unsigned long end_pfn);
void wait_for_freed_hugetlb_folios(void);
+
+struct mempolicy_interpreted {
+ int nid;
+ nodemask_t *nodemask;
+ enum mempolicy_mode mode;
+};
+
+enum hugetlb_alloc_flag {
+ HUGETLB_ALLOC_CHARGE_CGROUP_RSVD_BIT = 0,
+ HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS_BIT,
+};
+
+#define HUGETLB_ALLOC_CHARG_CGROUP_RSVD BIT(HUGETLB_ALLOC_CHARGE_CGROUP_RSVD_BIT)
+#define HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS BIT(HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS_BIT)
+
+struct folio *hugetlb_alloc_folio(struct hstate *h,
+ struct mempolicy_interpreted *mpoli, u8 alloc_flags);
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,
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 08ac28111e694..9a639800eb79c 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1317,12 +1317,6 @@ 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(struct hstate *h, gfp_t gfp_mask,
struct mempolicy_interpreted *mpoli)
{
@@ -2812,6 +2806,104 @@ void wait_for_freed_hugetlb_folios(void)
flush_work(&free_hpage_work);
}
+/**
+ * hugetlb_alloc_folio - Allocate a hugetlb folio.
+ * @h: Hugetlb state control block.
+ * @mpoli: Interpreted memory policy to use for allocation.
+ * @alloc_flags: Flags controlling the allocation behavior.
+ *
+ * Allocates a hugetlb folio and handles cgroup charging and global hstate
+ * reservations.
+ *
+ * Return: A pointer to the allocated folio, or an ERR_PTR on failure.
+ * -ENOSPC if cgroup charging fails or no folio is available.
+ * -ENOMEM if mem cgroup charging fails.
+ */
+struct folio *hugetlb_alloc_folio(struct hstate *h,
+ struct mempolicy_interpreted *mpoli, u8 alloc_flags)
+{
+ bool charge_hugetlb_cgroup_rsvd = alloc_flags &
+ HUGETLB_ALLOC_CHARG_CGROUP_RSVD;
+ bool use_global_reservation = alloc_flags &
+ HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS;
+ size_t nr_pages = pages_per_huge_page(h);
+ struct hugetlb_cgroup *h_cg_rsvd = NULL;
+ struct hugetlb_cgroup *h_cg = NULL;
+ gfp_t gfp = htlb_alloc_mask(h);
+ int idx = hstate_index(h);
+ struct folio *folio;
+ int ret;
+
+ if (charge_hugetlb_cgroup_rsvd &&
+ hugetlb_cgroup_charge_cgroup_rsvd(idx, nr_pages, &h_cg_rsvd))
+ return ERR_PTR(-ENOSPC);
+
+ if (hugetlb_cgroup_charge_cgroup(idx, nr_pages, &h_cg)) {
+ ret = -ENOSPC;
+ goto err_uncharge_hugetlb_cgroup_rsvd;
+ }
+
+ spin_lock_irq(&hugetlb_lock);
+
+ folio = NULL;
+ if (use_global_reservation || available_huge_pages(h))
+ folio = dequeue_hugetlb_folio(h, gfp, mpoli);
+
+ if (!folio) {
+ spin_unlock_irq(&hugetlb_lock);
+ folio = alloc_buddy_hugetlb_folio(h, gfp, mpoli);
+ if (!folio) {
+ ret = -ENOSPC;
+ goto err_uncharge_hugetlb_cgroup;
+ }
+ spin_lock_irq(&hugetlb_lock);
+ list_add(&folio->lru, &h->hugepage_activelist);
+ folio_ref_unfreeze(folio, 1);
+ }
+
+ if (use_global_reservation) {
+ folio_set_hugetlb_restore_reserve(folio);
+ h->resv_huge_pages--;
+ }
+
+ hugetlb_cgroup_commit_charge(idx, nr_pages, h_cg, folio);
+
+ if (charge_hugetlb_cgroup_rsvd) {
+ hugetlb_cgroup_commit_charge_rsvd(idx, nr_pages, h_cg_rsvd,
+ folio);
+ }
+
+ spin_unlock_irq(&hugetlb_lock);
+
+ ret = mem_cgroup_charge_hugetlb(folio, gfp | __GFP_RETRY_MAYFAIL);
+ /*
+ * Unconditionally increment NR_HUGETLB here because if
+ * mem_cgroup_charge_hugetlb failed, freeing the page will
+ * decrement NR_HUGETLB.
+ */
+ lruvec_stat_mod_folio(folio, NR_HUGETLB, nr_pages);
+
+ if (ret == -ENOMEM) {
+ free_huge_folio(folio);
+ /*
+ * Skip uncharging hugetlb_cgroup since the charges
+ * were committed to the folio and freeing the folio
+ * would have cleared those up.
+ */
+ return ERR_PTR(ret);
+ }
+
+ return folio;
+
+ err_uncharge_hugetlb_cgroup:
+ hugetlb_cgroup_uncharge_cgroup(idx, nr_pages, h_cg);
+ err_uncharge_hugetlb_cgroup_rsvd:
+ if (charge_hugetlb_cgroup_rsvd)
+ hugetlb_cgroup_uncharge_cgroup_rsvd(idx, nr_pages, h_cg_rsvd);
+
+ return ERR_PTR(ret);
+}
+
typedef enum {
/*
* For either 0/1: we checked the per-vma resv map, and one resv
@@ -2846,16 +2938,13 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
struct folio *folio;
long retval, gbl_chg, gbl_reserve;
map_chg_state map_chg;
- 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;
+ u8 alloc_flags = 0;
int nid;
-
- idx = hstate_index(h);
+ int ret;
/* Whether we need a separate per-vma reservation? */
if (cow_from_owner) {
@@ -2900,23 +2989,18 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
}
/*
- * If this allocation is not consuming a per-vma reservation,
- * charge the hugetlb cgroup now.
+ * If allocation doesn't reuse a reservation in the resv_map,
+ * charge for the reservation.
*/
- if (map_chg) {
- ret = hugetlb_cgroup_charge_cgroup_rsvd(
- idx, pages_per_huge_page(h), &h_cg_rsvd);
- if (ret) {
- ret = -ENOSPC;
- goto out_subpool_put;
- }
- }
+ if (map_chg != MAP_CHG_REUSE)
+ alloc_flags |= HUGETLB_ALLOC_CHARG_CGROUP_RSVD;
- ret = hugetlb_cgroup_charge_cgroup(idx, pages_per_huge_page(h), &h_cg);
- if (ret) {
- ret = -ENOSPC;
- goto out_uncharge_cgroup_reservation;
- }
+ /*
+ * gbl_chg == 0 indicates a reservation exists for this
+ * allocation, so try to use it.
+ */
+ if (gbl_chg == 0)
+ alloc_flags |= HUGETLB_ALLOC_USE_GLOBAL_RESERVATIONS;
/* Takes reference on mpol. */
nid = huge_node(vma, addr, gfp, &mpol, &nodemask);
@@ -2930,69 +3014,12 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
.nodemask = nodemask,
};
- spin_lock_irq(&hugetlb_lock);
-
- /*
- * gbl_chg == 0 indicates a reservation exists for the
- * allocation, so try dequeuing a page. In case there was no
- * reservation, try dequeuing a page if there are available
- * pages in the global pool.
- */
- folio = NULL;
- if (!gbl_chg || available_huge_pages(h))
- folio = dequeue_hugetlb_folio(h, gfp, &mpoli);
-
- if (!folio) {
- spin_unlock_irq(&hugetlb_lock);
- folio = alloc_buddy_hugetlb_folio(h, gfp, &mpoli);
- if (!folio) {
- mpol_cond_put(mpol);
- ret = -ENOSPC;
- goto out_uncharge_cgroup;
- }
- spin_lock_irq(&hugetlb_lock);
- list_add(&folio->lru, &h->hugepage_activelist);
- folio_ref_unfreeze(folio, 1);
- /* Fall through */
- }
+ folio = hugetlb_alloc_folio(h, &mpoli, alloc_flags);
mpol_cond_put(mpol);
- /*
- * Either dequeued or buddy-allocated folio needs to add special
- * mark to the folio when it consumes a global reservation.
- */
- if (!gbl_chg) {
- folio_set_hugetlb_restore_reserve(folio);
- h->resv_huge_pages--;
- }
-
- hugetlb_cgroup_commit_charge(idx, pages_per_huge_page(h), h_cg, folio);
- /* If allocation is not consuming a reservation, also store the
- * hugetlb_cgroup pointer on the page.
- */
- if (map_chg) {
- hugetlb_cgroup_commit_charge_rsvd(idx, pages_per_huge_page(h),
- h_cg_rsvd, folio);
- }
-
- spin_unlock_irq(&hugetlb_lock);
-
- 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
- * decrement NR_HUGETLB.
- */
- lruvec_stat_mod_folio(folio, NR_HUGETLB, pages_per_huge_page(h));
-
- if (ret == -ENOMEM) {
- free_huge_folio(folio);
- /*
- * Skip uncharging hugetlb_cgroup since the charges
- * were committed to the folio and freeing the folio
- * would have cleared those up.
- */
+ if (IS_ERR(folio)) {
+ ret = PTR_ERR(folio);
goto out_subpool_put;
}
@@ -3025,12 +3052,6 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
return folio;
-out_uncharge_cgroup:
- hugetlb_cgroup_uncharge_cgroup(idx, pages_per_huge_page(h), h_cg);
-out_uncharge_cgroup_reservation:
- if (map_chg)
- hugetlb_cgroup_uncharge_cgroup_rsvd(idx, pages_per_huge_page(h),
- h_cg_rsvd);
out_subpool_put:
/*
* put page to subpool iff the quota of subpool's rsv_hpages is used
@@ -3041,7 +3062,6 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
hugetlb_acct_memory(h, -gbl_reserve);
}
-
out_end_reservation:
if (map_chg != MAP_CHG_ENFORCED)
vma_end_reservation(h, vma, addr);
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use
2026-07-02 16:21 [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Ackerley Tng via B4 Relay
` (5 preceding siblings ...)
2026-07-02 16:21 ` [PATCH v4 6/6] mm: hugetlb: Refactor out hugetlb_alloc_folio() Ackerley Tng via B4 Relay
@ 2026-07-02 16:51 ` Zi Yan
2026-07-03 2:04 ` Qi Zheng
2026-07-02 22:12 ` Andrew Morton
7 siblings, 1 reply; 11+ messages in thread
From: Zi Yan @ 2026-07-02 16:51 UTC (permalink / raw)
To: Ackerley Tng, Qi Zheng
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Andrew Morton,
fvdl, jiaqiyan, joshua.hahnjy, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Matthew Brost, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Dan Williams,
Jason Gunthorpe, linux-mm, linux-kernel
+Qi
Since he is looking into adding memory reservation functionality to THP[1]
and this looks related.
[1] https://lore.kernel.org/all/cover.1782538002.git.zhengqi.arch@bytedance.com/
On 2 Jul 2026, at 12:21, Ackerley Tng via B4 Relay wrote:
> Hi,
>
> The motivation for this patch series is guest_memfd, which would like
> to use HugeTLB as a generic source of huge pages but not adopt
> HugeTLB's reservation at mmap() time.
>
> By refactoring alloc_hugetlb_folio() and some dependent functions,
> there is now an option to allocate HugeTLB folios without providing a
> VMA. Specifically, HugeTLB allocation used to be dependent on the VMA
> to
>
> 1. Look up reservations in the resv_map
> 2. Get mpol, stored at vma->vm_policy
>
> This refactoring provides hugetlb_alloc_folio(), which focuses on just
> the allocation itself, and associated memory and HugeTLB charging
> (cgroups). alloc_hugetlb_folio() still handles reservations in the
> resv_map and subpools.
>
> Regarding naming, I'm definitely open to alternative names :) I chose
> hugetlb_alloc_folio() because I'm seeing this function as a general
> allocation function that is provided by the HugeTLB subsystem (hence
> the hugetlb_ prefix). I'm intending for alloc_hugetlb_folio() to be
> later refactored as a static function for use just by HugeTLB, and
> HugeTLBfs should probably use hugetlb_alloc_folio() directly.
>
> To see how hugetlb_alloc_folio() is used by guest_memfd, the most
> recent patch series that uses this more generic HugeTLB allocation
> routine is at [1], and a newer revision of that patch series is at
> [2].
>
> Independently of guest_memfd, I believe this change is useful in
> simplifying alloc_hugetlb_folio(). alloc_hugetlb_folio() was so
> coupled to a VMA that even HugeTLBfs allocates HugeTLB folios using a
> pseudo-VMA.
>
> Testing:
>
> + libhugetlbfs tests pass
> + ./tools/testing/selftests/mm/ksft_hugetlb.sh passes
>
> Andrew, thanks for nudging me to send a v4!
>
> Oscar, you mentioned that you wanted to do a closer review on v3, hope you
> find time to review v4 soon!
>
> Changes in this revision:
>
> + Define gfp within hugetlb_alloc_folio() instead of having it as a
> parameter so users aren't able to override gfp arbitrarily as Oscar
> requested.
> + Addressed some of Sashiko's comments [4]. Some of the issues I didn't address
> were pre-existing issues. Since v3 of this series Sashiko was updated to
> actually send mails. I'd let Sashiko point them out again and then we should
> discuss those!
>
> [1] https://lore.kernel.org/all/cover.1747264138.git.ackerleytng@google.com/T/
> [2] https://github.com/googleprodkernel/linux-cc/tree/wip-gmem-conversions-hugetlb-restructuring-12-08-25
> [3] https://lore.kernel.org/all/agqaUcVp_hwH-VXr@localhost.localdomain/
> [4] https://sashiko.dev/#/patchset/20260518-hugetlb-open-up-v3-0-e14b302477f8@google.com
>
> 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
>
> ---
> Ackerley Tng (6):
> 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()
> mm: hugetlb: Use error variable in alloc_hugetlb_folio
> mm: hugetlb: Move mem_cgroup_charge_hugetlb() earlier in allocation
> mm: hugetlb: Refactor out hugetlb_alloc_folio()
>
> include/linux/hugetlb.h | 18 +++
> include/uapi/linux/mempolicy.h | 2 +-
> mm/hugetlb.c | 269 ++++++++++++++++++++++++-----------------
> 3 files changed, 175 insertions(+), 114 deletions(-)
> ---
> base-commit: 4a50a141f05a8d1737661b19ee22ff8455b94409
> change-id: 20260504-hugetlb-open-up-eaba80571b09
>
> Best regards,
> --
> Ackerley Tng <ackerleytng@google.com>
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use
2026-07-02 16:51 ` [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Zi Yan
@ 2026-07-03 2:04 ` Qi Zheng
0 siblings, 0 replies; 11+ messages in thread
From: Qi Zheng @ 2026-07-03 2:04 UTC (permalink / raw)
To: Zi Yan, Ackerley Tng
Cc: Muchun Song, Oscar Salvador, David Hildenbrand, Andrew Morton,
fvdl, jiaqiyan, joshua.hahnjy, jthoughton, mhocko, michael.roth,
pasha.tatashin, pbonzini, peterx, pratyush, rick.p.edgecombe,
rientjes, roman.gushchin, seanjc, shakeel.butt, shivankg,
vannapurve, yan.y.zhao, Matthew Brost, Rakie Kim, Byungchul Park,
Gregory Price, Ying Huang, Alistair Popple, Dan Williams,
Jason Gunthorpe, linux-mm, linux-kernel
Hi Zi,
On 7/3/26 12:51 AM, Zi Yan wrote:
> +Qi
Thanks for the CC! I'm very interested in this work and will
keep a close eye on this patchset.
Thanks,
Qi
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use
2026-07-02 16:21 [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Ackerley Tng via B4 Relay
` (6 preceding siblings ...)
2026-07-02 16:51 ` [PATCH v4 0/6] Open HugeTLB allocation routine for more generic use Zi Yan
@ 2026-07-02 22:12 ` Andrew Morton
7 siblings, 0 replies; 11+ messages in thread
From: Andrew Morton @ 2026-07-02 22:12 UTC (permalink / raw)
To: ackerleytng
Cc: Ackerley Tng via B4 Relay, Muchun Song, Oscar Salvador,
David Hildenbrand, fvdl, jiaqiyan, joshua.hahnjy, jthoughton,
mhocko, michael.roth, pasha.tatashin, pbonzini, peterx, pratyush,
rick.p.edgecombe, rientjes, roman.gushchin, seanjc, shakeel.butt,
shivankg, vannapurve, yan.y.zhao, Zi Yan, Matthew Brost,
Rakie Kim, Byungchul Park, Gregory Price, Ying Huang,
Alistair Popple, Dan Williams, Jason Gunthorpe, linux-mm,
linux-kernel
On Thu, 02 Jul 2026 09:21:44 -0700 Ackerley Tng via B4 Relay <devnull+ackerleytng.google.com@kernel.org> wrote:
> Hi,
>
> The motivation for this patch series is guest_memfd, which would like
> to use HugeTLB as a generic source of huge pages but not adopt
> HugeTLB's reservation at mmap() time.
>
> By refactoring alloc_hugetlb_folio() and some dependent functions,
> there is now an option to allocate HugeTLB folios without providing a
> VMA. Specifically, HugeTLB allocation used to be dependent on the VMA
> to
>
> 1. Look up reservations in the resv_map
> 2. Get mpol, stored at vma->vm_policy
>
> This refactoring provides hugetlb_alloc_folio(), which focuses on just
> the allocation itself, and associated memory and HugeTLB charging
> (cgroups). alloc_hugetlb_folio() still handles reservations in the
> resv_map and subpools.
Thanks, I added this to mm.git's mm-new branch.
As I understand it, the entire series is code shuffling and no
functional changes are intended.
> + Addressed some of Sashiko's comments [4]. Some of the issues I didn't address
> were pre-existing issues. Since v3 of this series Sashiko was updated to
> actually send mails. I'd let Sashiko point them out again and then we should
> discuss those!
Sashiko will send emails if configured to do so. For linux-mm, that is
turned off.
https://sashiko.dev/#/patchset/20260702-hugetlb-open-up-v4-0-d53cefcccf34@google.com
says "To: None Cc: None Status: Muted", so I don't think you received
those emails (did you?).
For some reason Sashiko did flag a couple of things which it didn't
consider to be pre-existing.
^ permalink raw reply [flat|nested] 11+ messages in thread