mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
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) <willy@infradead.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
74e8ee4708
commit
4ba1119cd5
@ -825,8 +825,14 @@ static inline int page_mapcount(struct page *page)
|
||||
return atomic_read(&page->_mapcount) + 1;
|
||||
}
|
||||
|
||||
int folio_mapcount(struct folio *folio);
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
int total_mapcount(struct page *page);
|
||||
static inline int total_mapcount(struct page *page)
|
||||
{
|
||||
return folio_mapcount(page_folio(page));
|
||||
}
|
||||
|
||||
int page_trans_huge_mapcount(struct page *page);
|
||||
#else
|
||||
static inline int total_mapcount(struct page *page)
|
||||
|
@ -2465,30 +2465,6 @@ static void __split_huge_page(struct page *page, struct list_head *list,
|
||||
}
|
||||
}
|
||||
|
||||
int total_mapcount(struct page *page)
|
||||
{
|
||||
int i, compound, nr, ret;
|
||||
|
||||
VM_BUG_ON_PAGE(PageTail(page), page);
|
||||
|
||||
if (likely(!PageCompound(page)))
|
||||
return atomic_read(&page->_mapcount) + 1;
|
||||
|
||||
compound = compound_mapcount(page);
|
||||
nr = compound_nr(page);
|
||||
if (PageHuge(page))
|
||||
return compound;
|
||||
ret = compound;
|
||||
for (i = 0; i < nr; i++)
|
||||
ret += atomic_read(&page[i]._mapcount) + 1;
|
||||
/* File pages has compound_mapcount included in _mapcount */
|
||||
if (!PageAnon(page))
|
||||
return ret - compound * nr;
|
||||
if (PageDoubleMap(page))
|
||||
ret -= nr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This calculates accurately how many mappings a transparent hugepage
|
||||
* has (unlike page_mapcount() which isn't fully accurate). This full
|
||||
|
33
mm/util.c
33
mm/util.c
@ -740,6 +740,39 @@ int __page_mapcount(struct page *page)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__page_mapcount);
|
||||
|
||||
/**
|
||||
* folio_mapcount() - Calculate the number of mappings of this folio.
|
||||
* @folio: The folio.
|
||||
*
|
||||
* A large folio tracks both how many times the entire folio is mapped,
|
||||
* and how many times each individual page in the folio is mapped.
|
||||
* This function calculates the total number of times the folio is
|
||||
* mapped.
|
||||
*
|
||||
* Return: The number of times this folio is mapped.
|
||||
*/
|
||||
int folio_mapcount(struct folio *folio)
|
||||
{
|
||||
int i, compound, nr, ret;
|
||||
|
||||
if (likely(!folio_test_large(folio)))
|
||||
return atomic_read(&folio->_mapcount) + 1;
|
||||
|
||||
compound = folio_entire_mapcount(folio);
|
||||
nr = folio_nr_pages(folio);
|
||||
if (folio_test_hugetlb(folio))
|
||||
return compound;
|
||||
ret = compound;
|
||||
for (i = 0; i < nr; i++)
|
||||
ret += atomic_read(&folio_page(folio, i)->_mapcount) + 1;
|
||||
/* File pages has compound_mapcount included in _mapcount */
|
||||
if (!folio_test_anon(folio))
|
||||
return ret - compound * nr;
|
||||
if (folio_test_double_map(folio))
|
||||
ret -= nr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* folio_copy - Copy the contents of one folio to another.
|
||||
* @dst: Folio to copy to.
|
||||
|
Loading…
Reference in New Issue
Block a user