diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/hugetlb.h | 6 | ||||
-rw-r--r-- | include/linux/mm.h | 32 |
2 files changed, 31 insertions, 7 deletions
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 251233c1494d..d01cc972a1d9 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h | |||
@@ -31,7 +31,6 @@ struct hugepage_subpool *hugepage_new_subpool(long nr_blocks); | |||
31 | void hugepage_put_subpool(struct hugepage_subpool *spool); | 31 | void hugepage_put_subpool(struct hugepage_subpool *spool); |
32 | 32 | ||
33 | int PageHuge(struct page *page); | 33 | int PageHuge(struct page *page); |
34 | int PageHeadHuge(struct page *page_head); | ||
35 | 34 | ||
36 | void reset_vma_resv_huge_pages(struct vm_area_struct *vma); | 35 | void reset_vma_resv_huge_pages(struct vm_area_struct *vma); |
37 | int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); | 36 | int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); |
@@ -104,11 +103,6 @@ static inline int PageHuge(struct page *page) | |||
104 | return 0; | 103 | return 0; |
105 | } | 104 | } |
106 | 105 | ||
107 | static inline int PageHeadHuge(struct page *page_head) | ||
108 | { | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma) | 106 | static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma) |
113 | { | 107 | { |
114 | } | 108 | } |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 9fac6dd69b11..f95c71b7c1fd 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -414,15 +414,45 @@ static inline int page_count(struct page *page) | |||
414 | return atomic_read(&compound_head(page)->_count); | 414 | return atomic_read(&compound_head(page)->_count); |
415 | } | 415 | } |
416 | 416 | ||
417 | #ifdef CONFIG_HUGETLB_PAGE | ||
418 | extern int PageHeadHuge(struct page *page_head); | ||
419 | #else /* CONFIG_HUGETLB_PAGE */ | ||
420 | static inline int PageHeadHuge(struct page *page_head) | ||
421 | { | ||
422 | return 0; | ||
423 | } | ||
424 | #endif /* CONFIG_HUGETLB_PAGE */ | ||
425 | |||
426 | static inline bool __compound_tail_refcounted(struct page *page) | ||
427 | { | ||
428 | return !PageSlab(page) && !PageHeadHuge(page); | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * This takes a head page as parameter and tells if the | ||
433 | * tail page reference counting can be skipped. | ||
434 | * | ||
435 | * For this to be safe, PageSlab and PageHeadHuge must remain true on | ||
436 | * any given page where they return true here, until all tail pins | ||
437 | * have been released. | ||
438 | */ | ||
439 | static inline bool compound_tail_refcounted(struct page *page) | ||
440 | { | ||
441 | VM_BUG_ON(!PageHead(page)); | ||
442 | return __compound_tail_refcounted(page); | ||
443 | } | ||
444 | |||
417 | static inline void get_huge_page_tail(struct page *page) | 445 | static inline void get_huge_page_tail(struct page *page) |
418 | { | 446 | { |
419 | /* | 447 | /* |
420 | * __split_huge_page_refcount() cannot run | 448 | * __split_huge_page_refcount() cannot run |
421 | * from under us. | 449 | * from under us. |
450 | * In turn no need of compound_trans_head here. | ||
422 | */ | 451 | */ |
423 | VM_BUG_ON(page_mapcount(page) < 0); | 452 | VM_BUG_ON(page_mapcount(page) < 0); |
424 | VM_BUG_ON(atomic_read(&page->_count) != 0); | 453 | VM_BUG_ON(atomic_read(&page->_count) != 0); |
425 | atomic_inc(&page->_mapcount); | 454 | if (compound_tail_refcounted(compound_head(page))) |
455 | atomic_inc(&page->_mapcount); | ||
426 | } | 456 | } |
427 | 457 | ||
428 | extern bool __get_page_tail(struct page *page); | 458 | extern bool __get_page_tail(struct page *page); |