Re: [PATCH] hugetlb: Do not account hugetlb pages as NR_FILE_PAGES

Michal Hocko
2015-06-02T09:25:45Z

On Mon 25-05-15 17:24:28, Vlastimil Babka wrote:
> On 05/22/2015 04:35 PM, Mel Gorman wrote:
> >>
> >> Thanks!
> >>
> >> > This makes a lot of sense to me. The only thing I worry about is the
> >> > proliferation of PageHuge(), a function call, in relatively hot paths.
> >>
> >> I've tried that (see the patch below) but it enlarged the code by almost
> >> 1k
> >> text data bss dec hex filename
> >> 510323 74273 44440 629036 9992c mm/built-in.o.before
> >> 511248 74273 44440 629961 99cc9 mm/built-in.o.after
> >>
> >> I am not sure the code size increase is worth it. Maybe we can reduce
> >> the check to only PageCompound(page) as huge pages are no in the page
> >> cache (yet).
> >>
> >
> > That would be a more sensible route because it also avoids exposing the
> > hugetlbfs destructor unnecessarily.
>
> You could maybe do test such as (PageCompound(page) && PageHuge(page)) to
> short-circuit the call while remaining future-proof.

How about this?
---
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 91b7f9b2b774..bb8a70e8fc77 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -547,7 +547,13 @@ static inline void ClearPageCompound(struct page *page)
#endif /* !PAGEFLAGS_EXTENDED */

#ifdef CONFIG_HUGETLB_PAGE
-int PageHuge(struct page *page);
+int __PageHuge(struct page *page);
+static inline int PageHuge(struct page *page)
+{
+ if (!PageCompound(page))
+ return 0;
+ return __PageHuge(page);
+}
int PageHeadHuge(struct page *page);
bool page_huge_active(struct page *page);
#else
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 33defbe1897f..648c0c32857c 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1107,19 +1107,17 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order)
}

/*
- * PageHuge() only returns true for hugetlbfs pages, but not for normal or
+ * __PageHuge() only returns true for hugetlbfs pages, but not for normal or
* transparent huge pages. See the PageTransHuge() documentation for more
* details.
*/
-int PageHuge(struct page *page)
+int __PageHuge(struct page *page)
{
- if (!PageCompound(page))
- return 0;
-
+ VM_BUG_ON(!PageCompound(page));
page = compound_head(page);
return get_compound_page_dtor(page) == free_huge_page;
}
-EXPORT_SYMBOL_GPL(PageHuge);
+EXPORT_SYMBOL_GPL(__PageHuge);

/*
* PageHeadHuge() only returns true for hugetlbfs head page, but not for

--
Michal Hocko
SUSE Labs