From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794270037; b=SsDgXwYGTrhMnBoHQhcWD8cBtTSp5WR7Gkzlql/a6n0Q0QCzq+mHKNLoBzAXzTzLlbI9 PCWlHVUFx6L2S0x505m0vibd3YzKoJrQR/XvdYWg2SOUaEQVZAT9QlcGcbFrQgCNjlz3V CVKoKuRBGRs8mWcuxfnooNvLrzL9K7snT4Wq0iCMmAHi0YMgbM+4mDaOYMuQJYmNpPM0V 2zxXUabhx0PnR5MNTsERJphdesUPQRFbPhI76shT/kZPPlye9lTN8R0R9A87HxE1w5ZO3 vAC2D3wHnQ7Am570233AlAl7IZI4a8xD/1pW0vVxWYlz0SwIebSPvXcXUcHfg1SXTPg== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794270037; h=Received:DKIM-Signature:Date:To:From:Subject:Message-Id; bh=6BMvH39CHetNODs8PuT95mQZbNEKK/BNaG54V6GhxsA=; b=scMvtxmHU0AKTVxvL6eMxUByY0lEOj0HRJlPw3KC1UmF42FMXHxBA8Nr4y7Gie9GXzdo tv/jF5l67Jls3ITLxfb8087OM5BtY7bmmRihSruz6mHwVoJ1F1OMDy+6PFojzdDx5y5nZ +bzqGt/DTa5jCA7ZWbZom7m0c50YC1H4VSbo90GvoErU6eJtdKhHZG1o45ORAOZkYwBit KxzqPbRJ47N9EjK6CkU66tGIqlfGuU3pK/SyFcccSBor0YIDBhun0FchtOhHgIxpVt5NN qcCQsEc14nOo8AIaQdYEALQj4w/o71TtabjpPjUzO3B7G8pvlMF9nMz5Ah/pmTYrDEg== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linux-foundation.org header.i=@linux-foundation.org header.a=rsa-sha256 header.s=korg header.b=div81HGD; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D989606A335 for ; Tue, 10 Nov 2026 00:20:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.a=rsa-sha256 header.s=korg header.b=div81HGD Received: by smtp.kernel.org (Postfix) with ESMTPSA id 444B41F008A2; Tue, 10 Nov 2026 00:20:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux-foundation.org; s=korg; t=1794270036; bh=6BMvH39CHetNODs8PuT95mQZbNEKK/BNaG54V6GhxsA=; h=Date:To:From:Subject; b=div81HGDS3k/8pC9euqmv6mPc6t++Z545kw1EEYIinwk+7/qDzQBwjeBsdKs/pRT9 rzl7QxVn9016AdOTbUb2VlAG+nWax+9Aq6t6gCuanVgATjhuadP2aYZlPwSJj7gvGa g3jCjH8zj0vPw7Rx6J8gwqTKf/F+Y5i//AXF0loc= Date: Mon, 09 Nov 2026 16:20:35 -0800 To: mm-commits@vger.kernel.org,chengkaitao@kylinos.cn, akpm@linux-foundation.org From: Andrew Morton Subject: [to-be-updated] mm-hugetlb-fix-nr_hugetlb-accounting-for-surplus-folios.patch removed from -mm tree Message-Id: <20261110002036.444B41F008A2@smtp.kernel.org> X-Mailing-List: mm-commits@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list The quilt patch titled Subject: mm/hugetlb: fix NR_HUGETLB accounting for surplus folios has been removed from the -mm tree. Its filename was mm-hugetlb-fix-nr_hugetlb-accounting-for-surplus-folios.patch This patch was dropped because an updated version will be issued ------------------------------------------------------ From: Kaitao Cheng Subject: mm/hugetlb: fix NR_HUGETLB accounting for surplus folios Date: Mon, 02 Nov 2026 10:49:10 +0800 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. Link: https://lore.kernel.org/20261102024910.31486-4-kaitao.cheng@linux.dev Fixes: 05d4532b60e3 ("memcg/hugetlb: add hugeTLB counters to memcg") Signed-off-by: Kaitao Cheng Signed-off-by: Andrew Morton Closes: https://sashiko.dev/#/bug/linux-860a3b8f-0b07-4cd5-a122-aa2288463bee Suggested-by: Muchun Song Suggested-by: Oscar Salvador Cc: David Hildenbrand Cc: Mike Rapoport Cc: Johannes Weiner Cc: Michal Hocko Cc: Roman Gushchin Cc: Shakeel Butt Cc: Mani Tofigh Cc: Zi Yan Cc: Baolin Wang Cc: Miaohe Lin Cc: Naoya Horiguchi Cc: Frank van der Linden Cc: Chris Down Cc: Joshua Hahn Cc: Qi Zheng --- mm/hugetlb.c | 42 +++++++++++++++++++++++++++--------------- mm/memcontrol.c | 6 +----- 2 files changed, 28 insertions(+), 20 deletions(-) --- a/mm/hugetlb.c~mm-hugetlb-fix-nr_hugetlb-accounting-for-surplus-folios +++ a/mm/hugetlb.c @@ -1288,6 +1288,8 @@ static struct folio *dequeue_hugetlb_fol 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 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 l 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_huget */ 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_huget spin_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_reserv 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_nodema nmask); } - if (folio) - lruvec_stat_mod_folio(folio, NR_HUGETLB, folio_nr_pages(folio)); - return folio; } @@ -2369,6 +2384,8 @@ retry: 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 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 return ERR_PTR(-ENOSPC); } + mod_hugetlb_memcg_state(folio, nr_pages); + return folio; err_uncharge_hugetlb_cgroup: --- a/mm/memcontrol.c~mm-hugetlb-fix-nr_hugetlb-accounting-for-surplus-folios +++ a/mm/memcontrol.c @@ -5439,11 +5439,7 @@ int mem_cgroup_charge_hugetlb(struct fol 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; _ Patches currently in -mm which might be from chengkaitao@kylinos.cn are