aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/hugetlb.h6
-rw-r--r--include/linux/mm.h32
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);
31void hugepage_put_subpool(struct hugepage_subpool *spool); 31void hugepage_put_subpool(struct hugepage_subpool *spool);
32 32
33int PageHuge(struct page *page); 33int PageHuge(struct page *page);
34int PageHeadHuge(struct page *page_head);
35 34
36void reset_vma_resv_huge_pages(struct vm_area_struct *vma); 35void reset_vma_resv_huge_pages(struct vm_area_struct *vma);
37int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); 36int 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
107static inline int PageHeadHuge(struct page *page_head)
108{
109 return 0;
110}
111
112static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma) 106static 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
418extern int PageHeadHuge(struct page *page_head);
419#else /* CONFIG_HUGETLB_PAGE */
420static inline int PageHeadHuge(struct page *page_head)
421{
422 return 0;
423}
424#endif /* CONFIG_HUGETLB_PAGE */
425
426static 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 */
439static inline bool compound_tail_refcounted(struct page *page)
440{
441 VM_BUG_ON(!PageHead(page));
442 return __compound_tail_refcounted(page);
443}
444
417static inline void get_huge_page_tail(struct page *page) 445static 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
428extern bool __get_page_tail(struct page *page); 458extern bool __get_page_tail(struct page *page);