On Wed, Sep 07, 2016 at 09:46:07AM -0700, Huang, Ying wrote: > From: Huang Ying <ying.huang@xxxxxxxxx> > > Separates checking whether we can split the huge page from > split_huge_page_to_list() into a function. This will help to check that > before splitting the THP (Transparent Huge Page) really. > > This will be used for delaying splitting THP during swapping out. Where > for a THP, we will allocate a swap cluster, add the THP into the swap > cache, then split the THP. To avoid the unnecessary operations for the > un-splittable THP, we will check that firstly. > > There is no functionality change in this patch. > > Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> > Cc: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> > Cc: Ebru Akagunduz <ebru.akagunduz@xxxxxxxxx> > Signed-off-by: "Huang, Ying" <ying.huang@xxxxxxxxx> > --- > include/linux/huge_mm.h | 6 ++++++ > mm/huge_memory.c | 13 ++++++++++++- > 2 files changed, 18 insertions(+), 1 deletion(-) > > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 9b9f65d..a0073e7 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -94,6 +94,7 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > extern void prep_transhuge_page(struct page *page); > extern void free_transhuge_page(struct page *page); > > +bool can_split_huge_page(struct page *page); > int split_huge_page_to_list(struct page *page, struct list_head *list); > static inline int split_huge_page(struct page *page) > { > @@ -176,6 +177,11 @@ static inline void prep_transhuge_page(struct page *page) {} > > #define thp_get_unmapped_area NULL > > +static inline bool > +can_split_huge_page(struct page *page) > +{ BUILD_BUG() should be appropriate here. > + return false; > +} > static inline int > split_huge_page_to_list(struct page *page, struct list_head *list) > { > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index fc0d37e..3be5abe 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -2016,6 +2016,17 @@ int page_trans_huge_mapcount(struct page *page, int *total_mapcount) > return ret; > } > > +/* Racy check whether the huge page can be split */ > +bool can_split_huge_page(struct page *page) > +{ > + int extra_pins = 0; > + > + /* Additional pins from radix tree */ > + if (!PageAnon(page)) > + extra_pins = HPAGE_PMD_NR; > + return total_mapcount(page) == page_count(page) - extra_pins - 1; > +} > + > /* > * This function splits huge page into normal pages. @page can point to any > * subpage of huge page to split. Split doesn't change the position of @page. > @@ -2086,7 +2097,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) > * Racy check if we can split the page, before freeze_page() will > * split PMDs > */ > - if (total_mapcount(head) != page_count(head) - extra_pins - 1) { > + if (!can_split_huge_page(head)) { > ret = -EBUSY; > goto out_unlock; > } > -- > 2.8.1 > -- Kirill A. Shutemov -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>