From: Barry Song <v-songbaohua@xxxxxxxx>
Anon large folios come from three places:
1. new allocated large folios in PF, they will call folio_add_new_anon_rmap()
for rmap;
2. a large folio is split into multiple lower-order large folios;
3. a large folio is migrated to a new large folio.
In all above three counts, we increase nr_anon by 1;
Anon large folios might go either because of be split or be put
to free, in these cases, we reduce the count by 1.
Folios that have been added to the swap cache but have not yet received
an anon mapping won't be counted. This is consistent with the AnonPages
statistics in /proc/meminfo.
Signed-off-by: Barry Song <v-songbaohua@xxxxxxxx>
---
Documentation/admin-guide/mm/transhuge.rst | 5 +++++
include/linux/huge_mm.h | 15 +++++++++++++--
mm/huge_memory.c | 13 ++++++++++---
mm/migrate.c | 4 ++++
mm/page_alloc.c | 5 ++++-
mm/rmap.c | 1 +
6 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/Documentation/admin-guide/mm/transhuge.rst b/Documentation/admin-guide/mm/transhuge.rst
index 058485daf186..9fdfb46e4560 100644
--- a/Documentation/admin-guide/mm/transhuge.rst
+++ b/Documentation/admin-guide/mm/transhuge.rst
@@ -527,6 +527,11 @@ split_deferred
it would free up some memory. Pages on split queue are going to
be split under memory pressure, if splitting is possible.
+nr_anon
+ the number of anon huge pages we have in the whole system.
@@ -447,6 +449,8 @@ static int __folio_migrate_mapping(struct address_space *mapping,
*/
newfolio->index = folio->index;
newfolio->mapping = folio->mapping;
+ if (folio_test_anon(folio) && folio_test_large(folio))
+ mod_mthp_stat(folio_order(folio), MTHP_STAT_NR_ANON, 1);
folio_ref_add(newfolio, nr); /* add cache reference */
if (folio_test_swapbacked(folio)) {
__folio_set_swapbacked(newfolio);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 84a7154fde93..382c364d3efa 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1084,8 +1084,11 @@ __always_inline bool free_pages_prepare(struct page *page,
(page + i)->flags &= ~PAGE_FLAGS_CHECK_AT_PREP;
}
}
- if (PageMappingFlags(page))
+ if (PageMappingFlags(page)) {
+ if (PageAnon(page) && compound)
+ mod_mthp_stat(order, MTHP_STAT_NR_ANON, -1);