This implements the same algorithm as total_mapcount(), which is transformed into a wrapper function.
Unified · Split
| @@ -825,8 +825,14 @@ static inline int page_mapcount(struct page *page) · 824 unmodified lines | ||
| 825 | 825 | return atomic_read(&page->_mapcount) + 1; |
| 826 | 826 | } |
| 827 | 827 | |
| 828 | +int folio_mapcount(struct folio *folio); | |
| 829 | + | |
| 828 | 830 | #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 | + | |
| 830 | 836 | int page_trans_huge_mapcount(struct page *page); |
| 831 | 837 | #else |
| 832 | 838 | static inline int total_mapcount(struct page *page) |
| @@ -2465,30 +2465,6 @@ static void __split_huge_page(struct page *page, struct list_head *list, · 2464 unmodified lines | ||
| 2465 | 2465 | } |
| 2466 | 2466 | } |
| 2467 | 2467 | |
| 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 | − | |
| 2492 | 2468 | /* |
| 2493 | 2469 | * This calculates accurately how many mappings a transparent hugepage |
| 2494 | 2470 | * has (unlike page_mapcount() which isn't fully accurate). This full |
| @@ -740,6 +740,39 @@ int __page_mapcount(struct page *page) · 739 unmodified lines | ||
| 740 | 740 | } |
| 741 | 741 | EXPORT_SYMBOL_GPL(__page_mapcount); |
| 742 | 742 | |
| 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 | + | |
| 743 | 776 | /** |
| 744 | 777 | * folio_copy - Copy the contents of one folio to another. |
| 745 | 778 | * @dst: Folio to copy to. |