Skip to content

Commit 4ba1119

Browse files
author
Matthew Wilcox (Oracle)
committed
mm: Add folio_mapcount()
This implements the same algorithm as total_mapcount(), which is transformed into a wrapper function. Signed-off-by: Matthew Wilcox (Oracle) <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent 74e8ee4 commit 4ba1119

File tree

3 files changed

+40
-25
lines changed

3 files changed

+40
-25
lines changed

include/linux/mm.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -825,8 +825,14 @@ static inline int page_mapcount(struct page *page)
825825
return atomic_read(&page->_mapcount) + 1;
826826
}
827827

828+
int folio_mapcount(struct folio *folio);
829+
828830
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
829-
int total_mapcount(struct page *page);
831+
static inline int total_mapcount(struct page *page)
832+
{
833+
return folio_mapcount(page_folio(page));
834+
}
835+
830836
int page_trans_huge_mapcount(struct page *page);
831837
#else
832838
static inline int total_mapcount(struct page *page)

mm/huge_memory.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2465,30 +2465,6 @@ static void __split_huge_page(struct page *page, struct list_head *list,
24652465
}
24662466
}
24672467

2468-
int total_mapcount(struct page *page)
2469-
{
2470-
int i, compound, nr, ret;
2471-
2472-
VM_BUG_ON_PAGE(PageTail(page), page);
2473-
2474-
if (likely(!PageCompound(page)))
2475-
return atomic_read(&page->_mapcount) + 1;
2476-
2477-
compound = compound_mapcount(page);
2478-
nr = compound_nr(page);
2479-
if (PageHuge(page))
2480-
return compound;
2481-
ret = compound;
2482-
for (i = 0; i < nr; i++)
2483-
ret += atomic_read(&page[i]._mapcount) + 1;
2484-
/* File pages has compound_mapcount included in _mapcount */
2485-
if (!PageAnon(page))
2486-
return ret - compound * nr;
2487-
if (PageDoubleMap(page))
2488-
ret -= nr;
2489-
return ret;
2490-
}
2491-
24922468
/*
24932469
* This calculates accurately how many mappings a transparent hugepage
24942470
* has (unlike page_mapcount() which isn't fully accurate). This full

mm/util.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,39 @@ int __page_mapcount(struct page *page)
740740
}
741741
EXPORT_SYMBOL_GPL(__page_mapcount);
742742

743+
/**
744+
* folio_mapcount() - Calculate the number of mappings of this folio.
745+
* @folio: The folio.
746+
*
747+
* A large folio tracks both how many times the entire folio is mapped,
748+
* and how many times each individual page in the folio is mapped.
749+
* This function calculates the total number of times the folio is
750+
* mapped.
751+
*
752+
* Return: The number of times this folio is mapped.
753+
*/
754+
int folio_mapcount(struct folio *folio)
755+
{
756+
int i, compound, nr, ret;
757+
758+
if (likely(!folio_test_large(folio)))
759+
return atomic_read(&folio->_mapcount) + 1;
760+
761+
compound = folio_entire_mapcount(folio);
762+
nr = folio_nr_pages(folio);
763+
if (folio_test_hugetlb(folio))
764+
return compound;
765+
ret = compound;
766+
for (i = 0; i < nr; i++)
767+
ret += atomic_read(&folio_page(folio, i)->_mapcount) + 1;
768+
/* File pages has compound_mapcount included in _mapcount */
769+
if (!folio_test_anon(folio))
770+
return ret - compound * nr;
771+
if (folio_test_double_map(folio))
772+
ret -= nr;
773+
return ret;
774+
}
775+
743776
/**
744777
* folio_copy - Copy the contents of one folio to another.
745778
* @dst: Folio to copy to.

0 commit comments

Comments
 (0)