History

mm: Add folio_mapcount()

This implements the same algorithm as total_mapcount(), which is transformed into a wrapper function.

Matthew Wilcox (Oracle) committed 4 years ago

Commit 4ba11191 parent 74e8ee43 files · +40 −25Browse files

Unified · Split

3 files
  1. include/linux/mm.h +7 −1
  2. mm/huge_memory.c +0 −24
  3. mm/util.c +33 −0
include/linux/mm.h+7−1
@@ -825,8 +825,14 @@ static inline int page_mapcount(struct page *page) · 824 unmodified lines
825 return atomic_read(&page->_mapcount) + 1;825 return atomic_read(&page->_mapcount) + 1;
826}826}
827 827
828int folio_mapcount(struct folio *folio);
829
828#ifdef CONFIG_TRANSPARENT_HUGEPAGE830#ifdef CONFIG_TRANSPARENT_HUGEPAGE
829int total_mapcount(struct page *page);831static inline int total_mapcount(struct page *page)
832{
833 return folio_mapcount(page_folio(page));
834}
835
830int page_trans_huge_mapcount(struct page *page);836int page_trans_huge_mapcount(struct page *page);
831#else837#else
832static inline int total_mapcount(struct page *page)838static inline int total_mapcount(struct page *page)
mm/huge_memory.c+0−24
@@ -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
2468int 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 * This calculates accurately how many mappings a transparent hugepage2469 * This calculates accurately how many mappings a transparent hugepage
2494 * has (unlike page_mapcount() which isn't fully accurate). This full2470 * has (unlike page_mapcount() which isn't fully accurate). This full
mm/util.c+33−0
@@ -740,6 +740,39 @@ int __page_mapcount(struct page *page) · 739 unmodified lines
740}740}
741EXPORT_SYMBOL_GPL(__page_mapcount);741EXPORT_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 */
754int 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 * folio_copy - Copy the contents of one folio to another.777 * folio_copy - Copy the contents of one folio to another.
745 * @dst: Folio to copy to.778 * @dst: Folio to copy to.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t