diff options
author | Andrea Arcangeli <aarcange@redhat.com> | 2011-01-13 18:46:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 20:32:39 -0500 |
commit | 9180706344487700b40da9eca5dedd3d11cb33b4 (patch) | |
tree | eb0347efe7e40adc78a271752c7382aa67875d6a /include/linux/mm.h | |
parent | e9da73d67729b58bba256123e2b4651e0d8a01ac (diff) |
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>
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r-- | include/linux/mm.h | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 3b1754ad8785..a2718e1ed585 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -353,9 +353,29 @@ static inline int page_count(struct page *page) | |||
353 | 353 | ||
354 | static inline void get_page(struct page *page) | 354 | static inline void get_page(struct page *page) |
355 | { | 355 | { |
356 | page = compound_head(page); | 356 | /* |
357 | VM_BUG_ON(atomic_read(&page->_count) == 0); | 357 | * Getting a normal page or the head of a compound page |
358 | * requires to already have an elevated page->_count. Only if | ||
359 | * we're getting a tail page, the elevated page->_count is | ||
360 | * required only in the head page, so for tail pages the | ||
361 | * bugcheck only verifies that the page->_count isn't | ||
362 | * negative. | ||
363 | */ | ||
364 | VM_BUG_ON(atomic_read(&page->_count) < !PageTail(page)); | ||
358 | atomic_inc(&page->_count); | 365 | atomic_inc(&page->_count); |
366 | /* | ||
367 | * Getting a tail page will elevate both the head and tail | ||
368 | * page->_count(s). | ||
369 | */ | ||
370 | if (unlikely(PageTail(page))) { | ||
371 | /* | ||
372 | * This is safe only because | ||
373 | * __split_huge_page_refcount can't run under | ||
374 | * get_page(). | ||
375 | */ | ||
376 | VM_BUG_ON(atomic_read(&page->first_page->_count) <= 0); | ||
377 | atomic_inc(&page->first_page->_count); | ||
378 | } | ||
359 | } | 379 | } |
360 | 380 | ||
361 | static inline struct page *virt_to_head_page(const void *x) | 381 | static inline struct page *virt_to_head_page(const void *x) |