mm/hugetlb: Fix CMA parsing, flags and usage accounting
Subsystems (4)
v2 cover mm/hugetlb: Fix CMA parsing, flags and usage accounting
This series fixes three independent HugeTLB issues reported by Sashiko, covering CMA parameter parsing, persistent folio flags, and NR_HUGETLB accounting on allocation rollback.
Patch 1 rejects a global hugetlb_cma size following node-specific entries. This prevents malformed input from overwriting valid per-node reservations with an incorrectly parsed global size.
Patch 2 preserves persistent folio flags when a failed vmemmap restore returns a folio to the pool. This retains CMA allocation tracking and raw hardware poison information, while ensuring transient flags are cleared before returning the folio.
Patch 3 moves NR_HUGETLB node accounting to the underlying folio state transitions and separates it from memcg statistics. This keeps the counter balanced when surplus folios are freed during reservation gathering or after a failed overcommit recheck.
Changes in v2:
- Patch 2: Preserve persistent flags, clear transient flags, and warn about unexpected flags.
- Patch 3: Account at folio state transitions and separate node and memcg statistics.
Link to v1:
https://lore.kernel.org/all/[email protected]/
Kaitao Cheng (3):
mm/hugetlb_cma: fix incorrect hugetlb_cma_size assignment on malformed
input
mm/hugetlb: Preserve persistent flags when returning folios to the
pool
mm/hugetlb: Fix NR_HUGETLB accounting for surplus folios
mm/hugetlb.c | 52 +++++++++++++++++++++++++++++++----------------- mm/hugetlb_cma.c | 3 +++ mm/memcontrol.c | 6 +----- 3 files changed, 38 insertions(+), 23 deletions(-)
Signature · 1 line
2.54.0 (Apple Git-157)
PATCH v2 1/3 mm/hugetlb_cma: fix incorrect hugetlb_cma_size assignment on malformed input
From: Kaitao Cheng <[email protected]>
When hugetlb_cma contains a global size after node-specific entries, cmdline_parse_hugetlb_cma() enters the global branch and reparses the original parameter string. For hugetlb_cma=1:2G,4G, this interprets the initial node ID as a one-byte global size and clears the 2 GiB reservation recorded for node 1.
Global and node-specific formats cannot be mixed. Return -EINVAL when a global entry follows a node-specific entry, before updating any settings. This preserves the valid prefix, so the example retains node 1's 2 GiB reservation and reports the malformed option.
--- mm/hugetlb_cma.c | 3 +++ 1 file changed, 3 insertions(+)
mm/hugetlb_cma.c +3 -0
@@ -167,6 +167,9 @@ static int __init cmdline_parse_hugetlb_cma(char *p) }else {char *next; +if (s != p) +return -EINVAL ; + tmp =memparse (p, &next);if (*next =='%' ) {if (tmp >100 ) {
Signature · 1 line
2.54.0 (Apple Git-157)
PATCH v2 2/3 mm/hugetlb: Preserve persistent flags when returning folios to the pool
In reply to Kaitao ChengFrom: Kaitao Cheng <[email protected]>
add_hugetlb_folio() returns a folio to the HugeTLB pool when vmemmap restoration fails. It clears folio->private and restores only HPG_vmemmap_optimized, losing other flags that must survive the rollback.
Clearing HPG_cma causes a later free to bypass the CMA release path, leaving the CMA allocation bitmap set. Clearing HPG_raw_hwp_unreliable loses the indication that the locations of poisoned subpages are unknown, undermining the checks that prevent freeing or unpoisoning such folios.
Preserve the existing flags instead of resetting folio->private. Callers already clear HPG_restore_reserve, HPG_migratable and HPG_freed before returning a folio to the pool. Clear HPG_temporary in free_huge_folio() before attempting to free a temporary folio, so a failed vmemmap restore does not leave that flag set on a folio returned as surplus.
Add a VM_WARN_ON_ONCE_FOLIO() check for flags other than HPG_vmemmap_optimized, HPG_raw_hwp_unreliable and HPG_cma to detect incomplete transient flag cleanup.
--- mm/hugetlb.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
mm/hugetlb.c +7 -3
@@ -1443,6 +1443,12 @@ void add_hugetlb_folio(struct hstate *h, struct folio *folio,lockdep_assert_held (&hugetlb_lock); +/* Callers must clear transient flags before returning to the pool. */ +VM_WARN_ON_ONCE_FOLIO ((unsigned long )folio->private & + ~(BIT (HPG_vmemmap_optimized) | +BIT (HPG_raw_hwp_unreliable) | +BIT (HPG_cma)), folio); +INIT_LIST_HEAD (&folio->lru); h->nr_huge_pages++; h->nr_huge_pages_node[nid]++;
@@ -1453,9 +1459,6 @@ void add_hugetlb_folio(struct hstate *h, struct folio *folio, }__folio_set_hugetlb (folio); -/* Clear all folio->private flags except hugetlb_vmemmap_optimized. */ - folio->private =NULL ; -folio_set_hugetlb_vmemmap_optimized (folio);arch_clear_hugetlb_flags (folio);enqueue_hugetlb_folio (h, folio);
@@ -1743,6 +1746,7 @@ void free_huge_folio(struct folio *folio) h->resv_huge_pages++;if (folio_test_hugetlb_temporary (folio)) { +folio_clear_hugetlb_temporary (folio);remove_hugetlb_folio (h, folio, false);spin_unlock_irqrestore (&hugetlb_lock, flags);update_and_free_hugetlb_folio (h, folio, true);
Signature · 1 line
2.54.0 (Apple Git-157)
Re: [PATCH v2 2/3] mm/hugetlb: Preserve persistent flags when returning folios to the pool
Quoted 25 lines · Kaitao Cheng
From: Kaitao Cheng <[email protected]>
add_hugetlb_folio()returns a folio to the HugeTLB pool when vmemmap restoration fails. It clearsfolio->privateand restores onlyHPG_vmemmap_optimized, losing other flags that must survive the rollback.Clearing
HPG_cmacauses a later free to bypass the CMA release path, leaving the CMA allocation bitmap set. ClearingHPG_raw_hwp_unreliableloses the indication that the locations of poisoned subpages are unknown, undermining the checks that prevent freeing or unpoisoning such folios.Preserve the existing flags instead of resetting
folio->private. Callers already clearHPG_restore_reserve,HPG_migratableandHPG_freedbefore returning a folio to the pool. ClearHPG_temporaryinfree_huge_folio()before attempting to free a temporary folio, so a failed vmemmap restore does not leave that flag set on a folio returned as surplus.Add a
VM_WARN_ON_ONCE_FOLIO()check for flags other thanHPG_vmemmap_optimized,HPG_raw_hwp_unreliableandHPG_cmato detect incomplete transient flag cleanup.
Quoted 7 lines
Fixes 161df60e9e89 ("mm, hwpoison, hugetlb: support saving mechanism of raw error pages")Fixes d2d786714080 ("mm/hugetlb: enable bootmem allocation from CMA areas")Suggested-by David Hildenbrand <[email protected]>Suggested-by Muchun Song <[email protected]>Suggested-by Zi Yan <[email protected]>Signed-off-by Kaitao Cheng <[email protected]>
But,
Quoted 9 lines
---
mm/hugetlb.c| 10 +++++++---1 file changed, 7 insertions(+), 3 deletions(-)mm/hugetlb.c +0
-0
mm/hugetlb.c void add_hugetlb_folio(struct hstate *h, struct folio *folio, · line 1448
Quoted 6 lines
mm/hugetlb.c +3
-0@@ -1443,6 +1443,12 @@ void add_hugetlb_folio(struct hstate *h, struct folio *folio,lockdep_assert_held (&hugetlb_lock); +/* Callers must clear transient flags before returning to the pool. */ + VM_WARN_ON_ONCE_FOLIO((unsigned long)folio->private & + ~(BIT(HPG_vmemmap_optimized) |
It looks like the parameters aren't aligned. A space missing before "~"?
Thanks.
Quoted 27 lines
mm/hugetlb.c +4
-3+BIT (HPG_raw_hwp_unreliable) | + BIT(HPG_cma)), folio); +INIT_LIST_HEAD (&folio->lru); h->nr_huge_pages++; h->nr_huge_pages_node[nid]++;@@ -1453,9 +1459,6 @@ void add_hugetlb_folio(struct hstate *h, struct folio *folio, }__folio_set_hugetlb (folio); -/* Clear all folio->private flags except hugetlb_vmemmap_optimized. */ - folio->private =NULL ; -folio_set_hugetlb_vmemmap_optimized (folio);arch_clear_hugetlb_flags (folio);enqueue_hugetlb_folio (h, folio);@@ -1743,6 +1746,7 @@ void free_huge_folio(struct folio *folio) h->resv_huge_pages++;if (folio_test_hugetlb_temporary (folio)) { +folio_clear_hugetlb_temporary (folio);remove_hugetlb_folio (h, folio, false);spin_unlock_irqrestore (&hugetlb_lock, flags);update_and_free_hugetlb_folio (h, folio, true);Signature · 1 line
2.54.0 (Apple Git-157)
Re: [PATCH v2 2/3] mm/hugetlb: Preserve persistent flags when returning folios to the pool
In reply to Kaitao ChengQuoted 28 lines · Kaitao Cheng
From: Kaitao Cheng <[email protected]>
add_hugetlb_folio()returns a folio to the HugeTLB pool when vmemmap restoration fails. It clearsfolio->privateand restores onlyHPG_vmemmap_optimized, losing other flags that must survive the rollback.Clearing
HPG_cmacauses a later free to bypass the CMA release path, leaving the CMA allocation bitmap set. ClearingHPG_raw_hwp_unreliableloses the indication that the locations of poisoned subpages are unknown, undermining the checks that prevent freeing or unpoisoning such folios.Preserve the existing flags instead of resetting
folio->private. Callers already clearHPG_restore_reserve,HPG_migratableandHPG_freedbefore returning a folio to the pool. ClearHPG_temporaryinfree_huge_folio()before attempting to free a temporary folio, so a failed vmemmap restore does not leave that flag set on a folio returned as surplus.Add a
VM_WARN_ON_ONCE_FOLIO()check for flags other thanHPG_vmemmap_optimized,HPG_raw_hwp_unreliableandHPG_cmato detect incomplete transient flag cleanup.Fixes 161df60e9e89 ("mm, hwpoison, hugetlb: support saving mechanism of raw error pages")Fixes d2d786714080 ("mm/hugetlb: enable bootmem allocation from CMA areas")Suggested-by David Hildenbrand <[email protected]>Suggested-by Muchun Song <[email protected]>Suggested-by Zi Yan <[email protected]>Signed-off-by Kaitao Cheng <[email protected]>
Quoted 4 lines
--- mm/hugetlb.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
Signature · 2 lines
Best Regards, Yan, Zi
Re: [PATCH v2 2/3] mm/hugetlb: Preserve persistent flags when returning folios to the pool
In reply to Kaitao ChengQuoted 28 lines · Kaitao Cheng
From: Kaitao Cheng <[email protected]>
add_hugetlb_folio()returns a folio to the HugeTLB pool when vmemmap restoration fails. It clearsfolio->privateand restores onlyHPG_vmemmap_optimized, losing other flags that must survive the rollback.Clearing
HPG_cmacauses a later free to bypass the CMA release path, leaving the CMA allocation bitmap set. ClearingHPG_raw_hwp_unreliableloses the indication that the locations of poisoned subpages are unknown, undermining the checks that prevent freeing or unpoisoning such folios.Preserve the existing flags instead of resetting
folio->private. Callers already clearHPG_restore_reserve,HPG_migratableandHPG_freedbefore returning a folio to the pool. ClearHPG_temporaryinfree_huge_folio()before attempting to free a temporary folio, so a failed vmemmap restore does not leave that flag set on a folio returned as surplus.Add a
VM_WARN_ON_ONCE_FOLIO()check for flags other thanHPG_vmemmap_optimized,HPG_raw_hwp_unreliableandHPG_cmato detect incomplete transient flag cleanup.Fixes 161df60e9e89 ("mm, hwpoison, hugetlb: support saving mechanism of raw error pages")Fixes d2d786714080 ("mm/hugetlb: enable bootmem allocation from CMA areas")Suggested-by David Hildenbrand <[email protected]>Suggested-by Muchun Song <[email protected]>Suggested-by Zi Yan <[email protected]>Signed-off-by Kaitao Cheng <[email protected]>
Quoted 3 lines
--- mm/hugetlb.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
Thanks,
Qi
PATCH v2 3/3 mm/hugetlb: Fix NR_HUGETLB accounting for surplus folios
In reply to Kaitao ChengFrom: Kaitao Cheng <[email protected]>
NR_HUGETLB is incremented in the allocation entry points, but decremented unconditionally in free_huge_folio(). Surplus folios allocated while gathering reservations can be freed without passing through those entry points, leaving an unmatched decrement in the per-node counter.
This happens when reservation gathering fails or allocates more folios than needed, or when the overcommit recheck rejects a newly allocated surplus folio. These paths cause nr_hugetlb in /proc/vmstat to underreport usage.
Move node accounting to the underlying folio state transitions. Increment NR_HUGETLB when dequeuing a free folio or allocating a fresh surplus or migration folio, and decrement it when returning the folio to the pool or removing it from active use. Balance the temporary increment when surplus folios gathered for reservations are added to the free pool.
Separate memcg statistics from node accounting, updating them after a successful charge and before uncharging. This keeps node accounting balanced independently of whether the folio is charged to a memcg.
--- mm/hugetlb.c | 42 +++++++++++++++++++++++++++--------------- mm/memcontrol.c | 6 +----- 2 files changed, 28 insertions(+), 20 deletions(-)
mm/hugetlb.c +27 -15
@@ -1288,6 +1288,8 @@ static struct folio *dequeue_hugetlb_folio_node_exact(struct hstate *h,folio_clear_hugetlb_freed (folio); h->free_huge_pages--; h->free_huge_pages_node[nid]--; +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB , +pages_per_huge_page (h));return folio; }
@@ -1416,6 +1418,9 @@ void remove_hugetlb_folio(struct hstate *h, struct folio *folio,folio_clear_hugetlb_freed (folio); h->free_huge_pages--; h->free_huge_pages_node[nid]--; + }else { +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB , + -(long )pages_per_huge_page (h)); }if (adjust_surplus) { h->surplus_huge_pages--;
@@ -1693,6 +1698,17 @@ struct hstate *size_to_hstate(unsigned long size)return NULL ; } +static void mod_hugetlb_memcg_state (struct folio *folio,int nr_pages) +{ +struct mem_cgroup *memcg; + +guard (rcu)(); + memcg =folio_memcg (folio); +if (memcg) +mod_memcg_lruvec_state (mem_cgroup_lruvec (memcg,folio_pgdat (folio)), +NR_HUGETLB , nr_pages); +} +void free_huge_folio (struct folio *folio) {/*
@@ -1740,7 +1756,7 @@ void free_huge_folio(struct folio *folio) pages_per_huge_page(h), folio);hugetlb_cgroup_uncharge_folio_rsvd (hstate_index (h),pages_per_huge_page (h), folio); -lruvec_stat_mod_folio (folio,NR_HUGETLB , -pages_per_huge_page (h)); +mod_hugetlb_memcg_state (folio, -pages_per_huge_page (h));mem_cgroup_uncharge (folio);if (restore_reserve) h->resv_huge_pages++;
@@ -1756,6 +1772,8 @@ void free_huge_folio(struct folio *folio)spin_unlock_irqrestore (&hugetlb_lock, flags);update_and_free_hugetlb_folio (h, folio, true); }else { +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB , + -(long )pages_per_huge_page (h));arch_clear_hugetlb_flags (folio);enqueue_hugetlb_folio (h, folio);spin_unlock_irqrestore (&hugetlb_lock, flags);
@@ -2123,6 +2141,9 @@ static struct folio *alloc_surplus_hugetlb_folio(struct hstate *h,*/ account_new_hugetlb_folio (h, folio); +/* The overcommit recheck below can free this folio. */ +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB ,pages_per_huge_page (h)); +/* * We could have raced with the pool size change. * Double check that and simply deallocate the new page
@@ -2160,6 +2181,7 @@ static struct folio *alloc_migrate_hugetlb_folio(struct hstate *h, gfp_t gfp_masspin_lock_irq (&hugetlb_lock);account_new_hugetlb_folio (h, folio); +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB ,pages_per_huge_page (h));spin_unlock_irq (&hugetlb_lock);/* fresh huge pages are frozen */
@@ -2218,10 +2240,6 @@ struct folio *alloc_hugetlb_folio_reserve(struct hstate *h, int preferred_nid,spin_unlock_irq (&hugetlb_lock); -if (folio) -lruvec_stat_mod_folio (folio,NR_HUGETLB , -folio_nr_pages (folio)); -return folio; }
@@ -2249,9 +2267,6 @@ struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid, nmask); } -if (folio) -lruvec_stat_mod_folio (folio,NR_HUGETLB ,folio_nr_pages (folio)); -return folio; }
@@ -2369,6 +2384,8 @@ static int gather_surplus_pages(struct hstate *h, long delta)if ((--needed) <0 )break ;/* Add the page to the hugetlb allocator */ +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB , + -(long )pages_per_huge_page (h));enqueue_hugetlb_folio (h, folio); } free:
@@ -2944,13 +2961,6 @@ struct folio *hugetlb_alloc_folio(struct hstate *h, ret =mem_cgroup_charge_hugetlb (folio, mm, 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 ) {folio_put (folio);/*
@@ -2965,6 +2975,8 @@ struct folio *hugetlb_alloc_folio(struct hstate *h,return ERR_PTR (-ENOSPC ); } +mod_hugetlb_memcg_state (folio, nr_pages); +return folio; err_uncharge_hugetlb_cgroup:
mm/memcontrol.c +1 -5
@@ -5417,11 +5417,7 @@ int mem_cgroup_charge_hugetlb(struct folio *folio, struct mm_struct *mm,struct mem_cgroup *memcg =get_mem_cgroup_from_mm (mm);int ret =0 ; -/* -* Even memcg does not account for hugetlb, we still want to update -* system-level stats via lruvec_stat_mod_folio. Return 0, and skip -* charging the memcg. -*/ +/* Skip charging unless hugetlb accounting is enabled for cgroup v2. */ if (mem_cgroup_disabled () || !memcg_accounts_hugetlb () || !memcg || !cgroup_subsys_on_dfl (memory_cgrp_subsys)) goto out;
Signature · 1 line
2.54.0 (Apple Git-157)
Muchun Song
maintainerRe: [PATCH v2 3/3] mm/hugetlb: Fix NR_HUGETLB accounting for surplus folios
Quoted 31 lines · Kaitao Cheng
From: Kaitao Cheng <[email protected]>
NR_HUGETLBis incremented in the allocation entry points, but decremented unconditionally infree_huge_folio(). Surplus folios allocated while gathering reservations can be freed without passing through those entry points, leaving an unmatched decrement in the per-node counter.This happens when reservation gathering fails or allocates more folios than needed, or when the overcommit recheck rejects a newly allocated surplus folio. These paths cause
nr_hugetlbin/proc/vmstatto underreport usage.Move node accounting to the underlying folio state transitions. Increment
NR_HUGETLBwhen dequeuing a free folio or allocating a fresh surplus or migration folio, and decrement it when returning the folio to the pool or removing it from active use. Balance the temporary increment when surplus folios gathered for reservations are added to the free pool.Separate memcg statistics from node accounting, updating them after a successful charge and before uncharging. This keeps node accounting balanced independently of whether the folio is charged to a memcg.
Fixes 05d4532b60e3 ("memcg/hugetlb: add hugeTLB counters to memcg")Suggested-by Muchun Song <[email protected]>Suggested-by Oscar Salvador <[email protected]>Signed-off-by Kaitao Cheng <[email protected]>
Quoted 4 lines
---
mm/hugetlb.c| 42 +++++++++++++++++++++++++++---------------mm/memcontrol.c| 6 +-----2 files changed, 28 insertions(+), 20 deletions(-)
I want to keep it simple for a backport fix, so your last version is good to me, and this one should be a cleanup based on the top of that.
Thanks.
Quoted 151 lines
mm/hugetlb.c +25
-8@@ -1288,6 +1288,8 @@ static struct folio *dequeue_hugetlb_folio_node_exact(struct hstate *h,folio_clear_hugetlb_freed (folio); h->free_huge_pages--; h->free_huge_pages_node[nid]--; +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB , +pages_per_huge_page (h));return folio; }@@ -1416,6 +1418,9 @@ void remove_hugetlb_folio(struct hstate *h, struct folio *folio,folio_clear_hugetlb_freed (folio); h->free_huge_pages--; h->free_huge_pages_node[nid]--; + }else { +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB , + -(long )pages_per_huge_page (h)); }if (adjust_surplus) { h->surplus_huge_pages--;@@ -1693,6 +1698,17 @@ struct hstate *size_to_hstate(unsigned long size)return NULL ; } +static void mod_hugetlb_memcg_state (struct folio *folio,int nr_pages) +{ +struct mem_cgroup *memcg; + +guard (rcu)(); + memcg =folio_memcg (folio); +if (memcg) +mod_memcg_lruvec_state (mem_cgroup_lruvec (memcg,folio_pgdat (folio)), +NR_HUGETLB , nr_pages); +} +void free_huge_folio (struct folio *folio) {/* @@ -1740,7 +1756,7 @@ void free_huge_folio(struct folio *folio) pages_per_huge_page(h), folio);hugetlb_cgroup_uncharge_folio_rsvd (hstate_index (h),pages_per_huge_page (h), folio); -lruvec_stat_mod_folio (folio,NR_HUGETLB , -pages_per_huge_page (h)); +mod_hugetlb_memcg_state (folio, -pages_per_huge_page (h));mem_cgroup_uncharge (folio);if (restore_reserve) h->resv_huge_pages++;@@ -1756,6 +1772,8 @@ void free_huge_folio(struct folio *folio)spin_unlock_irqrestore (&hugetlb_lock, flags);update_and_free_hugetlb_folio (h, folio, true); }else { +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB , + -(long )pages_per_huge_page (h));arch_clear_hugetlb_flags (folio);enqueue_hugetlb_folio (h, folio);spin_unlock_irqrestore (&hugetlb_lock, flags);@@ -2123,6 +2141,9 @@ static struct folio *alloc_surplus_hugetlb_folio(struct hstate *h,*/ account_new_hugetlb_folio (h, folio); +/* The overcommit recheck below can free this folio. */ +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB ,pages_per_huge_page (h)); +/* * We could have raced with the pool size change. * Double check that and simply deallocate the new page @@ -2160,6 +2181,7 @@ static struct folio *alloc_migrate_hugetlb_folio(struct hstate *h, gfp_t gfp_masspin_lock_irq (&hugetlb_lock);account_new_hugetlb_folio (h, folio); +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB ,pages_per_huge_page (h));spin_unlock_irq (&hugetlb_lock);/* fresh huge pages are frozen */ @@ -2218,10 +2240,6 @@ struct folio *alloc_hugetlb_folio_reserve(struct hstate *h, int preferred_nid,spin_unlock_irq (&hugetlb_lock); -if (folio) -lruvec_stat_mod_folio (folio,NR_HUGETLB , -folio_nr_pages (folio)); -return folio; }@@ -2249,9 +2267,6 @@ struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid, nmask); } -if (folio) -lruvec_stat_mod_folio (folio,NR_HUGETLB ,folio_nr_pages (folio)); -return folio; }@@ -2369,6 +2384,8 @@ static int gather_surplus_pages(struct hstate *h, long delta)if ((--needed) <0 )break ;/* Add the page to the hugetlb allocator */ +mod_node_page_state (folio_pgdat (folio),NR_HUGETLB , + -(long )pages_per_huge_page (h));enqueue_hugetlb_folio (h, folio); }free:
mm/hugetlb.c +2
-7@@ -2944,13 +2961,6 @@ struct folio *hugetlb_alloc_folio(struct hstate *h, ret =mem_cgroup_charge_hugetlb (folio, mm, 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 ) {folio_put (folio);/* @@ -2965,6 +2975,8 @@ struct folio *hugetlb_alloc_folio(struct hstate *h,return ERR_PTR (-ENOSPC ); } +mod_hugetlb_memcg_state (folio, nr_pages); +return folio; err_uncharge_hugetlb_cgroup:mm/memcontrol.c +1
-5@@ -5417,11 +5417,7 @@ int mem_cgroup_charge_hugetlb(struct folio *folio, struct mm_struct *mm,struct mem_cgroup *memcg =get_mem_cgroup_from_mm (mm);int ret =0 ; -/* -* Even memcg does not account for hugetlb, we still want to update -* system-level stats via lruvec_stat_mod_folio. Return 0, and skip -* charging the memcg. -*/ +/* Skip charging unless hugetlb accounting is enabled for cgroup v2. */ if (mem_cgroup_disabled () || !memcg_accounts_hugetlb () || !memcg || !cgroup_subsys_on_dfl (memory_cgrp_subsys)) goto out;Signature · 1 line
2.54.0 (Apple Git-157)