mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-23 07:01:23 +00:00
thp: alter compound get_page/put_page
Alter compound get_page/put_page to keep references on subpages too, in order to allow __split_huge_page_refcount to split an hugepage even while subpages have been pinned by one of the get_user_pages() variants. Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Acked-by: Rik van Riel <riel@redhat.com> Acked-by: Mel Gorman <mel@csn.ul.ie> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
e9da73d677
commit
9180706344
4 changed files with 129 additions and 9 deletions
|
@ -353,9 +353,29 @@ static inline int page_count(struct page *page)
|
|||
|
||||
static inline void get_page(struct page *page)
|
||||
{
|
||||
page = compound_head(page);
|
||||
VM_BUG_ON(atomic_read(&page->_count) == 0);
|
||||
/*
|
||||
* Getting a normal page or the head of a compound page
|
||||
* requires to already have an elevated page->_count. Only if
|
||||
* we're getting a tail page, the elevated page->_count is
|
||||
* required only in the head page, so for tail pages the
|
||||
* bugcheck only verifies that the page->_count isn't
|
||||
* negative.
|
||||
*/
|
||||
VM_BUG_ON(atomic_read(&page->_count) < !PageTail(page));
|
||||
atomic_inc(&page->_count);
|
||||
/*
|
||||
* Getting a tail page will elevate both the head and tail
|
||||
* page->_count(s).
|
||||
*/
|
||||
if (unlikely(PageTail(page))) {
|
||||
/*
|
||||
* This is safe only because
|
||||
* __split_huge_page_refcount can't run under
|
||||
* get_page().
|
||||
*/
|
||||
VM_BUG_ON(atomic_read(&page->first_page->_count) <= 0);
|
||||
atomic_inc(&page->first_page->_count);
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct page *virt_to_head_page(const void *x)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue