diff options
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r-- | include/linux/mm.h | 67 |
1 files changed, 33 insertions, 34 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 3b3e3b8bb706..3dc3a8c2c485 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -356,36 +356,50 @@ static inline struct page *compound_head(struct page *page) | |||
356 | return page; | 356 | return page; |
357 | } | 357 | } |
358 | 358 | ||
359 | /* | ||
360 | * The atomic page->_mapcount, starts from -1: so that transitions | ||
361 | * both from it and to it can be tracked, using atomic_inc_and_test | ||
362 | * and atomic_add_negative(-1). | ||
363 | */ | ||
364 | static inline void reset_page_mapcount(struct page *page) | ||
365 | { | ||
366 | atomic_set(&(page)->_mapcount, -1); | ||
367 | } | ||
368 | |||
369 | static inline int page_mapcount(struct page *page) | ||
370 | { | ||
371 | return atomic_read(&(page)->_mapcount) + 1; | ||
372 | } | ||
373 | |||
359 | static inline int page_count(struct page *page) | 374 | static inline int page_count(struct page *page) |
360 | { | 375 | { |
361 | return atomic_read(&compound_head(page)->_count); | 376 | return atomic_read(&compound_head(page)->_count); |
362 | } | 377 | } |
363 | 378 | ||
379 | static inline void get_huge_page_tail(struct page *page) | ||
380 | { | ||
381 | /* | ||
382 | * __split_huge_page_refcount() cannot run | ||
383 | * from under us. | ||
384 | */ | ||
385 | VM_BUG_ON(page_mapcount(page) < 0); | ||
386 | VM_BUG_ON(atomic_read(&page->_count) != 0); | ||
387 | atomic_inc(&page->_mapcount); | ||
388 | } | ||
389 | |||
390 | extern bool __get_page_tail(struct page *page); | ||
391 | |||
364 | static inline void get_page(struct page *page) | 392 | static inline void get_page(struct page *page) |
365 | { | 393 | { |
394 | if (unlikely(PageTail(page))) | ||
395 | if (likely(__get_page_tail(page))) | ||
396 | return; | ||
366 | /* | 397 | /* |
367 | * Getting a normal page or the head of a compound page | 398 | * Getting a normal page or the head of a compound page |
368 | * requires to already have an elevated page->_count. Only if | 399 | * requires to already have an elevated page->_count. |
369 | * we're getting a tail page, the elevated page->_count is | ||
370 | * required only in the head page, so for tail pages the | ||
371 | * bugcheck only verifies that the page->_count isn't | ||
372 | * negative. | ||
373 | */ | 400 | */ |
374 | VM_BUG_ON(atomic_read(&page->_count) < !PageTail(page)); | 401 | VM_BUG_ON(atomic_read(&page->_count) <= 0); |
375 | atomic_inc(&page->_count); | 402 | atomic_inc(&page->_count); |
376 | /* | ||
377 | * Getting a tail page will elevate both the head and tail | ||
378 | * page->_count(s). | ||
379 | */ | ||
380 | if (unlikely(PageTail(page))) { | ||
381 | /* | ||
382 | * This is safe only because | ||
383 | * __split_huge_page_refcount can't run under | ||
384 | * get_page(). | ||
385 | */ | ||
386 | VM_BUG_ON(atomic_read(&page->first_page->_count) <= 0); | ||
387 | atomic_inc(&page->first_page->_count); | ||
388 | } | ||
389 | } | 403 | } |
390 | 404 | ||
391 | static inline struct page *virt_to_head_page(const void *x) | 405 | static inline struct page *virt_to_head_page(const void *x) |
@@ -804,21 +818,6 @@ static inline pgoff_t page_index(struct page *page) | |||
804 | } | 818 | } |
805 | 819 | ||
806 | /* | 820 | /* |
807 | * The atomic page->_mapcount, like _count, starts from -1: | ||
808 | * so that transitions both from it and to it can be tracked, | ||
809 | * using atomic_inc_and_test and atomic_add_negative(-1). | ||
810 | */ | ||
811 | static inline void reset_page_mapcount(struct page *page) | ||
812 | { | ||
813 | atomic_set(&(page)->_mapcount, -1); | ||
814 | } | ||
815 | |||
816 | static inline int page_mapcount(struct page *page) | ||
817 | { | ||
818 | return atomic_read(&(page)->_mapcount) + 1; | ||
819 | } | ||
820 | |||
821 | /* | ||
822 | * Return true if this page is mapped into pagetables. | 821 | * Return true if this page is mapped into pagetables. |
823 | */ | 822 | */ |
824 | static inline int page_mapped(struct page *page) | 823 | static inline int page_mapped(struct page *page) |