From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55C932DECA3 for ; Thu, 23 Apr 2026 20:31:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776976263; cv=none; b=P1mH9ayKcFsGmeZLgFgODsjeiXeN/nTNQ7OwFTCUX0bkuf/H43PdGZaGKfRoelOhy9UhRL+AZHMBPAdcB5EmO9EQ2hv21801oZANsLz/WaqJ6kdmLiKrzNGQGDW2EgGBdIYFw3NzIqpPheRzXUSNITxSCujVF5KC9jD0elRejV0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776976263; c=relaxed/simple; bh=UP/jnBvh08Z0y81/mysMZj72WUk+hiqmAQsgr0HTVNk=; h=Date:To:From:Subject:Message-Id; b=aYhdpVdM4nW4gfWKg2Oc3GUNraEWI89INBsskB0dlsEU48fuT+CAYH7P4/2402VSE/FMMI7ISaee0GbW1iEfiSq6OzN0LZjLdBbM4ula0BJO2hLpy/W2cIocRsH5kVm8f59HC92Lt894h445wsZxVsI1T4zGJBcYBg1vXr4PAA0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=Rb0tLyp9; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="Rb0tLyp9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 178C3C2BCAF; Thu, 23 Apr 2026 20:31:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1776976263; bh=UP/jnBvh08Z0y81/mysMZj72WUk+hiqmAQsgr0HTVNk=; h=Date:To:From:Subject:From; b=Rb0tLyp9zI8tHkdTXt4Y1qzD0geMjWrQ056eMFYk70URyg1QTwqpN9/onpjHWGG7F K6jJjTjR3bUxisYq1vrCL4/lUCiECQJgY8B5nDoYmTN4e5gCENSiInsC6lJki5Qylm rvUUtHtlClSbkONHHeEBTQNbsZkzPqK04N6EuG7c= Date: Thu, 23 Apr 2026 13:31:02 -0700 To: mm-commits@vger.kernel.org,npache@redhat.com,akpm@linux-foundation.org From: Andrew Morton Subject: + mm-khugepaged-add-per-order-mthp-collapse-failure-statistics.patch added to mm-new branch Message-Id: <20260423203103.178C3C2BCAF@smtp.kernel.org> Precedence: bulk X-Mailing-List: mm-commits@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: The patch titled Subject: mm/khugepaged: add per-order mTHP collapse failure statistics has been added to the -mm mm-new branch. Its filename is mm-khugepaged-add-per-order-mthp-collapse-failure-statistics.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-khugepaged-add-per-order-mthp-collapse-failure-statistics.patch This patch will later appear in the mm-new branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Note, mm-new is a provisional staging ground for work-in-progress patches, and acceptance into mm-new is a notification for others take notice and to finish up reviews. Please do not hesitate to respond to review feedback and post updated versions to replace or incrementally fixup patches in mm-new. The mm-new branch of mm.git is not included in linux-next If a few days of testing in mm-new is successful, the patch will me moved into mm.git's mm-unstable branch, which is included in linux-next Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via various branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there most days ------------------------------------------------------ From: Nico Pache Subject: mm/khugepaged: add per-order mTHP collapse failure statistics Date: Sun, 19 Apr 2026 12:57:44 -0600 Add three new mTHP statistics to track collapse failures for different orders when encountering swap PTEs, excessive none PTEs, and shared PTEs: - collapse_exceed_swap_pte: Increment when mTHP collapse fails due to swap PTEs - collapse_exceed_none_pte: Counts when mTHP collapse fails due to exceeding the none PTE threshold for the given order - collapse_exceed_shared_pte: Counts when mTHP collapse fails due to shared PTEs These statistics complement the existing THP_SCAN_EXCEED_* events by providing per-order granularity for mTHP collapse attempts. The stats are exposed via sysfs under `/sys/kernel/mm/transparent_hugepage/hugepages-*/stats/` for each supported hugepage size. As we currently dont support collapsing mTHPs that contain a swap or shared entry, those statistics keep track of how often we are encountering failed mTHP collapses due to these restrictions. Now that we plan to support mTHP collapse for anon pages, lets also track when this happens at the PMD level within the per-mTHP stats. Link: https://lore.kernel.org/20260419185750.260784-8-npache@redhat.com Signed-off-by: Nico Pache Cc: Alistair Popple Cc: Andrea Arcangeli Cc: Anshuman Khandual Cc: Bagas Sanjaya Cc: Baolin Wang Cc: Barry Song Cc: Brendan Jackman Cc: Byungchul Park Cc: Catalin Marinas Cc: David Hildenbrand (Arm) Cc: David Rientjes Cc: Dev Jain Cc: Gregory Price Cc: "Huang, Ying" Cc: Hugh Dickins Cc: Jan Kara Cc: Jann Horn Cc: Johannes Weiner Cc: Jonathan Corbet Cc: Joshua Hahn Cc: Kefeng Wang Cc: Lance Yang Cc: Liam Howlett Cc: Lorenzo Stoakes Cc: "Masami Hiramatsu (Google)" Cc: Mathieu Desnoyers Cc: Matthew Brost Cc: Matthew Wilcox (Oracle) Cc: Michal Hocko Cc: Mike Rapoport Cc: Nanyong Sun Cc: Pedro Falcato Cc: Peter Xu Cc: Rafael Aquini Cc: Rakie Kim Cc: Randy Dunlap Cc: Ryan Roberts Cc: Shivank Garg Cc: Steven Rostedt Cc: Suren Baghdasaryan Cc: Takashi Iwai (SUSE) Cc: Thomas Hellström Cc: Usama Arif Cc: Vishal Moola (Oracle) Cc: Vlastimil Babka Cc: Wei Yang Cc: Will Deacon Cc: Yang Shi Cc: Zach O'Keefe Cc: Zi Yan Signed-off-by: Andrew Morton --- Documentation/admin-guide/mm/transhuge.rst | 24 +++++++++++++++++++ include/linux/huge_mm.h | 3 ++ mm/huge_memory.c | 7 +++++ mm/khugepaged.c | 21 +++++++++++++++- 4 files changed, 53 insertions(+), 2 deletions(-) --- a/Documentation/admin-guide/mm/transhuge.rst~mm-khugepaged-add-per-order-mthp-collapse-failure-statistics +++ a/Documentation/admin-guide/mm/transhuge.rst @@ -714,6 +714,30 @@ nr_anon_partially_mapped an anonymous THP as "partially mapped" and count it here, even though it is not actually partially mapped anymore. +collapse_exceed_none_pte + The number of collapse attempts that failed due to exceeding the + max_ptes_none threshold. For mTHP collapse, Currently only max_ptes_none + values of 0 and (HPAGE_PMD_NR - 1) are supported. Any other value will + emit a warning and no mTHP collapse will be attempted. khugepaged will + try to collapse to the largest enabled (m)THP size; if it fails, it will + try the next lower enabled mTHP size. This counter records the number of + times a collapse attempt was skipped for exceeding the max_ptes_none + threshold, and khugepaged will move on to the next available mTHP size. + +collapse_exceed_swap_pte + The number of anonymous mTHP PTE ranges which were unable to collapse due + to containing at least one swap PTE. Currently khugepaged does not + support collapsing mTHP regions that contain a swap PTE. This counter can + be used to monitor the number of khugepaged mTHP collapses that failed + due to the presence of a swap PTE. + +collapse_exceed_shared_pte + The number of anonymous mTHP PTE ranges which were unable to collapse due + to containing at least one shared PTE. Currently khugepaged does not + support collapsing mTHP PTE ranges that contain a shared PTE. This + counter can be used to monitor the number of khugepaged mTHP collapses + that failed due to the presence of a shared PTE. + As the system ages, allocating huge pages may be expensive as the system uses memory compaction to copy data around memory to free a huge page for use. There are some counters in ``/proc/vmstat`` to help --- a/include/linux/huge_mm.h~mm-khugepaged-add-per-order-mthp-collapse-failure-statistics +++ a/include/linux/huge_mm.h @@ -144,6 +144,9 @@ enum mthp_stat_item { MTHP_STAT_SPLIT_DEFERRED, MTHP_STAT_NR_ANON, MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, + MTHP_STAT_COLLAPSE_EXCEED_SWAP, + MTHP_STAT_COLLAPSE_EXCEED_NONE, + MTHP_STAT_COLLAPSE_EXCEED_SHARED, __MTHP_STAT_COUNT }; --- a/mm/huge_memory.c~mm-khugepaged-add-per-order-mthp-collapse-failure-statistics +++ a/mm/huge_memory.c @@ -703,6 +703,10 @@ DEFINE_MTHP_STAT_ATTR(split_failed, MTHP DEFINE_MTHP_STAT_ATTR(split_deferred, MTHP_STAT_SPLIT_DEFERRED); DEFINE_MTHP_STAT_ATTR(nr_anon, MTHP_STAT_NR_ANON); DEFINE_MTHP_STAT_ATTR(nr_anon_partially_mapped, MTHP_STAT_NR_ANON_PARTIALLY_MAPPED); +DEFINE_MTHP_STAT_ATTR(collapse_exceed_swap_pte, MTHP_STAT_COLLAPSE_EXCEED_SWAP); +DEFINE_MTHP_STAT_ATTR(collapse_exceed_none_pte, MTHP_STAT_COLLAPSE_EXCEED_NONE); +DEFINE_MTHP_STAT_ATTR(collapse_exceed_shared_pte, MTHP_STAT_COLLAPSE_EXCEED_SHARED); + static struct attribute *anon_stats_attrs[] = { &anon_fault_alloc_attr.attr, @@ -719,6 +723,9 @@ static struct attribute *anon_stats_attr &split_deferred_attr.attr, &nr_anon_attr.attr, &nr_anon_partially_mapped_attr.attr, + &collapse_exceed_swap_pte_attr.attr, + &collapse_exceed_none_pte_attr.attr, + &collapse_exceed_shared_pte_attr.attr, NULL, }; --- a/mm/khugepaged.c~mm-khugepaged-add-per-order-mthp-collapse-failure-statistics +++ a/mm/khugepaged.c @@ -646,7 +646,9 @@ static enum scan_result __collapse_huge_ if (pte_none_or_zero(pteval)) { if (++none_or_zero > max_ptes_none) { result = SCAN_EXCEED_NONE_PTE; - count_vm_event(THP_SCAN_EXCEED_NONE_PTE); + if (is_pmd_order(order)) + count_vm_event(THP_SCAN_EXCEED_NONE_PTE); + count_mthp_stat(order, MTHP_STAT_COLLAPSE_EXCEED_NONE); goto out; } continue; @@ -680,9 +682,17 @@ static enum scan_result __collapse_huge_ /* See collapse_scan_pmd(). */ if (folio_maybe_mapped_shared(folio)) { + /* + * TODO: Support shared pages without leading to further + * mTHP collapses. Currently bringing in new pages via + * shared may cause a future higher order collapse on a + * rescan of the same range. + */ if (++shared > max_ptes_shared) { result = SCAN_EXCEED_SHARED_PTE; - count_vm_event(THP_SCAN_EXCEED_SHARED_PTE); + if (is_pmd_order(order)) + count_vm_event(THP_SCAN_EXCEED_SHARED_PTE); + count_mthp_stat(order, MTHP_STAT_COLLAPSE_EXCEED_SHARED); goto out; } } @@ -1129,6 +1139,7 @@ static enum scan_result __collapse_huge_ * range. */ if (!is_pmd_order(order)) { + count_mthp_stat(order, MTHP_STAT_COLLAPSE_EXCEED_SWAP); pte_unmap(pte); mmap_read_unlock(mm); result = SCAN_EXCEED_SWAP_PTE; @@ -1412,6 +1423,8 @@ static enum scan_result collapse_scan_pm if (++none_or_zero > max_ptes_none) { result = SCAN_EXCEED_NONE_PTE; count_vm_event(THP_SCAN_EXCEED_NONE_PTE); + count_mthp_stat(HPAGE_PMD_ORDER, + MTHP_STAT_COLLAPSE_EXCEED_NONE); goto out_unmap; } continue; @@ -1420,6 +1433,8 @@ static enum scan_result collapse_scan_pm if (++unmapped > max_ptes_swap) { result = SCAN_EXCEED_SWAP_PTE; count_vm_event(THP_SCAN_EXCEED_SWAP_PTE); + count_mthp_stat(HPAGE_PMD_ORDER, + MTHP_STAT_COLLAPSE_EXCEED_SWAP); goto out_unmap; } /* @@ -1477,6 +1492,8 @@ static enum scan_result collapse_scan_pm if (++shared > max_ptes_shared) { result = SCAN_EXCEED_SHARED_PTE; count_vm_event(THP_SCAN_EXCEED_SHARED_PTE); + count_mthp_stat(HPAGE_PMD_ORDER, + MTHP_STAT_COLLAPSE_EXCEED_SHARED); goto out_unmap; } } _ Patches currently in -mm which might be from npache@redhat.com are mm-khugepaged-generalize-hugepage_vma_revalidate-for-mthp-support.patch mm-khugepaged-rework-max_ptes_-handling-with-helper-functions.patch mm-khugepaged-generalize-__collapse_huge_page_-for-mthp-support.patch mm-khugepaged-generalize-collapse_huge_page-for-mthp-collapse.patch mm-khugepaged-skip-collapsing-mthp-to-smaller-orders.patch mm-khugepaged-add-per-order-mthp-collapse-failure-statistics.patch mm-khugepaged-improve-tracepoints-for-mthp-orders.patch mm-khugepaged-introduce-collapse_allowable_orders-helper-function.patch mm-khugepaged-introduce-mthp-collapse-support.patch mm-khugepaged-avoid-unnecessary-mthp-collapse-attempts.patch documentation-mm-update-the-admin-guide-for-mthp-collapse.patch