From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-f198.google.com (mail-pf0-f198.google.com [209.85.192.198]) by kanga.kvack.org (Postfix) with ESMTP id 52D416B0033 for ; Mon, 16 Oct 2017 05:26:32 -0400 (EDT) Received: by mail-pf0-f198.google.com with SMTP id v78so14218010pfk.8 for ; Mon, 16 Oct 2017 02:26:32 -0700 (PDT) Received: from mga05.intel.com (mga05.intel.com. [192.55.52.43]) by mx.google.com with ESMTPS id 185si4124078pfu.388.2017.10.16.02.26.31 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Oct 2017 02:26:31 -0700 (PDT) From: changbin.du@intel.com Subject: [PATCH 0/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Date: Mon, 16 Oct 2017 17:19:15 +0800 Message-Id: <1508145557-9944-1-git-send-email-changbin.du@intel.com> Sender: owner-linux-mm@kvack.org List-ID: To: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Changbin Du From: Changbin Du The first one introduce new interfaces, the second one kills naming confusion. The aim is to remove duplicated code and simplify transparent huge page allocation. Changbin Du (2): mm, thp: introduce dedicated transparent huge page allocation interfaces mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Documentation/vm/hugetlbfs_reserv.txt | 4 +-- include/linux/gfp.h | 4 --- include/linux/huge_mm.h | 15 ++++++++-- include/linux/hugetlb.h | 2 +- include/linux/migrate.h | 14 ++++----- include/linux/mm.h | 8 +++--- mm/huge_memory.c | 54 +++++++++++++++++++++++++++++------ mm/hugetlb.c | 14 ++++----- mm/khugepaged.c | 11 ++----- mm/mempolicy.c | 10 ++----- mm/migrate.c | 12 +++----- mm/page_alloc.c | 10 +++---- mm/shmem.c | 6 ++-- mm/swap.c | 2 +- mm/userfaultfd.c | 2 +- 15 files changed, 95 insertions(+), 73 deletions(-) -- 2.7.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f71.google.com (mail-pg0-f71.google.com [74.125.83.71]) by kanga.kvack.org (Postfix) with ESMTP id A07F16B0069 for ; Mon, 16 Oct 2017 05:26:35 -0400 (EDT) Received: by mail-pg0-f71.google.com with SMTP id i196so6036382pgd.2 for ; Mon, 16 Oct 2017 02:26:35 -0700 (PDT) Received: from mga05.intel.com (mga05.intel.com. [192.55.52.43]) by mx.google.com with ESMTPS id 185si4124078pfu.388.2017.10.16.02.26.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Oct 2017 02:26:34 -0700 (PDT) From: changbin.du@intel.com Subject: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Date: Mon, 16 Oct 2017 17:19:16 +0800 Message-Id: <1508145557-9944-2-git-send-email-changbin.du@intel.com> In-Reply-To: <1508145557-9944-1-git-send-email-changbin.du@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> Sender: owner-linux-mm@kvack.org List-ID: To: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Changbin Du From: Changbin Du This patch introduced 4 new interfaces to allocate a prepared transparent huge page. - alloc_transhuge_page_vma - alloc_transhuge_page_nodemask - alloc_transhuge_page_node - alloc_transhuge_page The aim is to remove duplicated code and simplify transparent huge page allocation. These are similar to alloc_hugepage_xxx which are for hugetlbfs pages. This patch does below changes: - define alloc_transhuge_page_xxx interfaces - apply them to all existing code - declare prep_transhuge_page as static since no others use it - remove alloc_hugepage_vma definition since it no longer has users Signed-off-by: Changbin Du --- include/linux/gfp.h | 4 ---- include/linux/huge_mm.h | 13 ++++++++++++- include/linux/migrate.h | 14 +++++--------- mm/huge_memory.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- mm/khugepaged.c | 11 ++--------- mm/mempolicy.c | 10 +++------- mm/migrate.c | 12 ++++-------- mm/shmem.c | 6 ++---- 8 files changed, 71 insertions(+), 49 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index f780718..855c72e 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -507,15 +507,11 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, struct vm_area_struct *vma, unsigned long addr, int node, bool hugepage); -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ - alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) #else #define alloc_pages(gfp_mask, order) \ alloc_pages_node(numa_node_id(), gfp_mask, order) #define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ alloc_pages(gfp_mask, order) -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ - alloc_pages(gfp_mask, order) #endif #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) #define alloc_page_vma(gfp_mask, vma, addr) \ diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 14bc21c..1dd2c33 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); -extern void prep_transhuge_page(struct page *page); extern void free_transhuge_page(struct page *page); +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, + struct vm_area_struct *vma, unsigned long addr); +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, + int preferred_nid, nodemask_t *nmask); + +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gfp_mask) +{ + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); +} + +struct page *alloc_transhuge_page(gfp_t gfp_mask); + bool can_split_huge_page(struct page *page, int *pextra_pins); int split_huge_page_to_list(struct page *page, struct list_head *list); static inline int split_huge_page(struct page *page) diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 643c7ae..70a00f3 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct page *page, return alloc_huge_page_nodemask(page_hstate(compound_head(page)), preferred_nid, nodemask); - if (thp_migration_supported() && PageTransHuge(page)) { - order = HPAGE_PMD_ORDER; - gfp_mask |= GFP_TRANSHUGE; - } - if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) gfp_mask |= __GFP_HIGHMEM; - new_page = __alloc_pages_nodemask(gfp_mask, order, + if (thp_migration_supported() && PageTransHuge(page)) + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, + preferred_nid, nodemask); + else + return __alloc_pages_nodemask(gfp_mask, order, preferred_nid, nodemask); - - if (new_page && PageTransHuge(page)) - prep_transhuge_page(new_page); return new_page; } diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 269b5df..e267488 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(struct page *page) return (struct list_head *)&page[2].mapping; } -void prep_transhuge_page(struct page *page) +static void prep_transhuge_page(struct page *page) { /* * we use page->mapping and page->indexlru in second tail page @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); } +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, + struct vm_area_struct *vma, unsigned long addr) +{ + struct page *page; + + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, + vma, addr, numa_node_id(), true); + if (unlikely(!page)) + return NULL; + prep_transhuge_page(page); + return page; +} + +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, + int preferred_nid, nodemask_t *nmask) +{ + struct page *page; + + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, + preferred_nid, nmask); + if (unlikely(!page)) + return NULL; + prep_transhuge_page(page); + return page; +} + +struct page *alloc_transhuge_page(gfp_t gfp_mask) +{ + struct page *page; + + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); + + page = alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); + if (unlikely(!page)) + return NULL; + prep_transhuge_page(page); + return page; +} + unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, loff_t off, unsigned long flags, unsigned long size) { @@ -719,12 +758,11 @@ int do_huge_pmd_anonymous_page(struct vm_fault *vmf) return ret; } gfp = alloc_hugepage_direct_gfpmask(vma); - page = alloc_hugepage_vma(gfp, vma, haddr, HPAGE_PMD_ORDER); + page = alloc_transhuge_page_vma(gfp, vma, haddr); if (unlikely(!page)) { count_vm_event(THP_FAULT_FALLBACK); return VM_FAULT_FALLBACK; } - prep_transhuge_page(page); return __do_huge_pmd_anonymous_page(vmf, page, gfp); } @@ -1288,13 +1326,11 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) if (transparent_hugepage_enabled(vma) && !transparent_hugepage_debug_cow()) { huge_gfp = alloc_hugepage_direct_gfpmask(vma); - new_page = alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDER); + new_page = alloc_transhuge_page_vma(huge_gfp, vma, haddr); } else new_page = NULL; - if (likely(new_page)) { - prep_transhuge_page(new_page); - } else { + if (unlikely(!new_page)) { if (!page) { split_huge_pmd(vma, vmf->pmd, vmf->address); ret |= VM_FAULT_FALLBACK; diff --git a/mm/khugepaged.c b/mm/khugepaged.c index c01f177..d17a694 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -745,14 +745,13 @@ khugepaged_alloc_page(struct page **hpage, gfp_t gfp, int node) { VM_BUG_ON_PAGE(*hpage, *hpage); - *hpage = __alloc_pages_node(node, gfp, HPAGE_PMD_ORDER); + *hpage = alloc_transhuge_page_node(node, gfp); if (unlikely(!*hpage)) { count_vm_event(THP_COLLAPSE_ALLOC_FAILED); *hpage = ERR_PTR(-ENOMEM); return NULL; } - prep_transhuge_page(*hpage); count_vm_event(THP_COLLAPSE_ALLOC); return *hpage; } @@ -764,13 +763,7 @@ static int khugepaged_find_target_node(void) static inline struct page *alloc_khugepaged_hugepage(void) { - struct page *page; - - page = alloc_pages(alloc_hugepage_khugepaged_gfpmask(), - HPAGE_PMD_ORDER); - if (page) - prep_transhuge_page(page); - return page; + return alloc_transhuge_page(alloc_hugepage_khugepaged_gfpmask()); } static struct page *khugepaged_alloc_hugepage(bool *wait) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index a2af6d5..aa24285 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -949,12 +949,10 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x else if (thp_migration_supported() && PageTransHuge(page)) { struct page *thp; - thp = alloc_pages_node(node, - (GFP_TRANSHUGE | __GFP_THISNODE), - HPAGE_PMD_ORDER); + thp = alloc_transhuge_page_node(node, + (GFP_TRANSHUGE | __GFP_THISNODE)); if (!thp) return NULL; - prep_transhuge_page(thp); return thp; } else return __alloc_pages_node(node, GFP_HIGHUSER_MOVABLE | @@ -1125,11 +1123,9 @@ static struct page *new_page(struct page *page, unsigned long start, int **x) } else if (thp_migration_supported() && PageTransHuge(page)) { struct page *thp; - thp = alloc_hugepage_vma(GFP_TRANSHUGE, vma, address, - HPAGE_PMD_ORDER); + thp = alloc_transhuge_page_vma(GFP_TRANSHUGE, vma, address); if (!thp) return NULL; - prep_transhuge_page(thp); return thp; } /* diff --git a/mm/migrate.c b/mm/migrate.c index e00814c..7f0486f 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1472,12 +1472,10 @@ static struct page *new_page_node(struct page *p, unsigned long private, else if (thp_migration_supported() && PageTransHuge(p)) { struct page *thp; - thp = alloc_pages_node(pm->node, - (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM, - HPAGE_PMD_ORDER); + thp = alloc_transhuge_page_node(pm->node, + (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM); if (!thp) return NULL; - prep_transhuge_page(thp); return thp; } else return __alloc_pages_node(pm->node, @@ -2017,12 +2015,10 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, if (numamigrate_update_ratelimit(pgdat, HPAGE_PMD_NR)) goto out_dropref; - new_page = alloc_pages_node(node, - (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE), - HPAGE_PMD_ORDER); + new_page = alloc_transhuge_page_node(node, + (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE)); if (!new_page) goto out_fail; - prep_transhuge_page(new_page); isolated = numamigrate_isolate_page(pgdat, page); if (!isolated) { diff --git a/mm/shmem.c b/mm/shmem.c index 07a1d22..52468f7 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1444,11 +1444,9 @@ static struct page *shmem_alloc_hugepage(gfp_t gfp, rcu_read_unlock(); shmem_pseudo_vma_init(&pvma, info, hindex); - page = alloc_pages_vma(gfp | __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN, - HPAGE_PMD_ORDER, &pvma, 0, numa_node_id(), true); + gfp |= __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN; + page = alloc_transhuge_page_vma(gfp, &pvma, 0); shmem_pseudo_vma_destroy(&pvma); - if (page) - prep_transhuge_page(page); return page; } -- 2.7.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-f197.google.com (mail-pf0-f197.google.com [209.85.192.197]) by kanga.kvack.org (Postfix) with ESMTP id 5058D6B0253 for ; Mon, 16 Oct 2017 05:26:39 -0400 (EDT) Received: by mail-pf0-f197.google.com with SMTP id x7so14302561pfa.19 for ; Mon, 16 Oct 2017 02:26:39 -0700 (PDT) Received: from mga05.intel.com (mga05.intel.com. [192.55.52.43]) by mx.google.com with ESMTPS id 185si4124078pfu.388.2017.10.16.02.26.37 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Oct 2017 02:26:38 -0700 (PDT) From: changbin.du@intel.com Subject: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Date: Mon, 16 Oct 2017 17:19:17 +0800 Message-Id: <1508145557-9944-3-git-send-email-changbin.du@intel.com> In-Reply-To: <1508145557-9944-1-git-send-email-changbin.du@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> Sender: owner-linux-mm@kvack.org List-ID: To: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Changbin Du From: Changbin Du The current name free_{huge,transhuge}_page are paired with alloc_{huge,transhuge}_page functions, but the actual page free function is still free_page() which will indirectly call free_{huge,transhuge}_page. So this patch removes this confusion by renaming all the compound page dtors. Signed-off-by: Changbin Du --- Documentation/vm/hugetlbfs_reserv.txt | 4 ++-- include/linux/huge_mm.h | 2 +- include/linux/hugetlb.h | 2 +- include/linux/mm.h | 8 ++++---- mm/huge_memory.c | 4 ++-- mm/hugetlb.c | 14 +++++++------- mm/page_alloc.c | 10 +++++----- mm/swap.c | 2 +- mm/userfaultfd.c | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Documentation/vm/hugetlbfs_reserv.txt b/Documentation/vm/hugetlbfs_reserv.txt index 9aca09a..b3ffa3e 100644 --- a/Documentation/vm/hugetlbfs_reserv.txt +++ b/Documentation/vm/hugetlbfs_reserv.txt @@ -238,7 +238,7 @@ to the global reservation count (resv_huge_pages). Freeing Huge Pages ------------------ -Huge page freeing is performed by the routine free_huge_page(). This routine +Huge page freeing is performed by the routine huge_page_dtor(). This routine is the destructor for hugetlbfs compound pages. As a result, it is only passed a pointer to the page struct. When a huge page is freed, reservation accounting may need to be performed. This would be the case if the page was @@ -468,7 +468,7 @@ However, there are several instances where errors are encountered after a huge page is allocated but before it is instantiated. In this case, the page allocation has consumed the reservation and made the appropriate subpool, reservation map and global count adjustments. If the page is freed at this -time (before instantiation and clearing of PagePrivate), then free_huge_page +time (before instantiation and clearing of PagePrivate), then huge_page_dtor will increment the global reservation count. However, the reservation map indicates the reservation was consumed. This resulting inconsistent state will cause the 'leak' of a reserved huge page. The global reserve count will diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 1dd2c33..40ae3058 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -130,7 +130,7 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); -extern void free_transhuge_page(struct page *page); +extern void transhuge_page_dtor(struct page *page); struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, struct vm_area_struct *vma, unsigned long addr); diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 8bbbd37..24492c5 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -118,7 +118,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, long freed); bool isolate_huge_page(struct page *page, struct list_head *list); void putback_active_hugepage(struct page *page); -void free_huge_page(struct page *page); +void huge_page_dtor(struct page *page); void hugetlb_fix_reserve_counts(struct inode *inode); extern struct mutex *hugetlb_fault_mutex_table; u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, diff --git a/include/linux/mm.h b/include/linux/mm.h index 065d99d..adfa906 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -616,7 +616,7 @@ void split_page(struct page *page, unsigned int order); * prototype for that function and accessor functions. * These are _only_ valid on the head of a compound page. */ -typedef void compound_page_dtor(struct page *); +typedef void compound_page_dtor_t(struct page *); /* Keep the enum in sync with compound_page_dtors array in mm/page_alloc.c */ enum compound_dtor_id { @@ -630,7 +630,7 @@ enum compound_dtor_id { #endif NR_COMPOUND_DTORS, }; -extern compound_page_dtor * const compound_page_dtors[]; +extern compound_page_dtor_t * const compound_page_dtors[]; static inline void set_compound_page_dtor(struct page *page, enum compound_dtor_id compound_dtor) @@ -639,7 +639,7 @@ static inline void set_compound_page_dtor(struct page *page, page[1].compound_dtor = compound_dtor; } -static inline compound_page_dtor *get_compound_page_dtor(struct page *page) +static inline compound_page_dtor_t *get_compound_page_dtor(struct page *page) { VM_BUG_ON_PAGE(page[1].compound_dtor >= NR_COMPOUND_DTORS, page); return compound_page_dtors[page[1].compound_dtor]; @@ -657,7 +657,7 @@ static inline void set_compound_order(struct page *page, unsigned int order) page[1].compound_order = order; } -void free_compound_page(struct page *page); +void compound_page_dtor(struct page *page); #ifdef CONFIG_MMU /* diff --git a/mm/huge_memory.c b/mm/huge_memory.c index e267488..a01125b 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2717,7 +2717,7 @@ fail: if (mapping) return ret; } -void free_transhuge_page(struct page *page) +void transhuge_page_dtor(struct page *page) { struct pglist_data *pgdata = NODE_DATA(page_to_nid(page)); unsigned long flags; @@ -2728,7 +2728,7 @@ void free_transhuge_page(struct page *page) list_del(page_deferred_list(page)); } spin_unlock_irqrestore(&pgdata->split_queue_lock, flags); - free_compound_page(page); + compound_page_dtor(page); } void deferred_split_huge_page(struct page *page) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 424b0ef..1af2c4e7 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1250,7 +1250,7 @@ static void clear_page_huge_active(struct page *page) ClearPagePrivate(&page[1]); } -void free_huge_page(struct page *page) +void huge_page_dtor(struct page *page) { /* * Can't pass hstate in here because it is called from the @@ -1363,7 +1363,7 @@ int PageHeadHuge(struct page *page_head) if (!PageHead(page_head)) return 0; - return get_compound_page_dtor(page_head) == free_huge_page; + return get_compound_page_dtor(page_head) == huge_page_dtor; } pgoff_t __basepage_index(struct page *page) @@ -1932,11 +1932,11 @@ static long vma_add_reservation(struct hstate *h, * specific error paths, a huge page was allocated (via alloc_huge_page) * and is about to be freed. If a reservation for the page existed, * alloc_huge_page would have consumed the reservation and set PagePrivate - * in the newly allocated page. When the page is freed via free_huge_page, + * in the newly allocated page. When the page is freed via huge_page_dtor, * the global reservation count will be incremented if PagePrivate is set. - * However, free_huge_page can not adjust the reserve map. Adjust the + * However, huge_page_dtor can not adjust the reserve map. Adjust the * reserve map here to be consistent with global reserve count adjustments - * to be made by free_huge_page. + * to be made by huge_page_dtor. */ static void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma, unsigned long address, @@ -1950,7 +1950,7 @@ static void restore_reserve_on_error(struct hstate *h, * Rare out of memory condition in reserve map * manipulation. Clear PagePrivate so that * global reserve count will not be incremented - * by free_huge_page. This will make it appear + * by huge_page_dtor. This will make it appear * as though the reservation for this page was * consumed. This may prevent the task from * faulting in the page at a later time. This @@ -2304,7 +2304,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, while (count > persistent_huge_pages(h)) { /* * If this allocation races such that we no longer need the - * page, free_huge_page will handle it by freeing the page + * page, huge_page_dtor will handle it by freeing the page * and reducing the surplus. */ spin_unlock(&hugetlb_lock); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 77e4d3c..b31205c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -248,14 +248,14 @@ char * const migratetype_names[MIGRATE_TYPES] = { #endif }; -compound_page_dtor * const compound_page_dtors[] = { +compound_page_dtor_t * const compound_page_dtors[] = { NULL, - free_compound_page, + compound_page_dtor, #ifdef CONFIG_HUGETLB_PAGE - free_huge_page, + huge_page_dtor, #endif #ifdef CONFIG_TRANSPARENT_HUGEPAGE - free_transhuge_page, + transhuge_page_dtor, #endif }; @@ -586,7 +586,7 @@ static void bad_page(struct page *page, const char *reason, * This usage means that zero-order pages may not be compound. */ -void free_compound_page(struct page *page) +void compound_page_dtor(struct page *page) { __free_pages_ok(page, compound_order(page)); } diff --git a/mm/swap.c b/mm/swap.c index a77d68f..8f98caf 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -81,7 +81,7 @@ static void __put_single_page(struct page *page) static void __put_compound_page(struct page *page) { - compound_page_dtor *dtor; + compound_page_dtor_t *dtor; /* * __page_cache_release() is supposed to be called for thp, not for diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 8119270..91d9045 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -323,7 +323,7 @@ static __always_inline ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, * map of a private mapping, the map was modified to indicate * the reservation was consumed when the page was allocated. * We clear the PagePrivate flag now so that the global - * reserve count will not be incremented in free_huge_page. + * reserve count will not be incremented in huge_page_dtor. * The reservation map will still indicate the reservation * was consumed and possibly prevent later page allocation. * This is better than leaking a global reservation. If no -- 2.7.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qk0-f198.google.com (mail-qk0-f198.google.com [209.85.220.198]) by kanga.kvack.org (Postfix) with ESMTP id 7FC4E6B0253 for ; Tue, 17 Oct 2017 04:08:20 -0400 (EDT) Received: by mail-qk0-f198.google.com with SMTP id f199so1105563qke.20 for ; Tue, 17 Oct 2017 01:08:20 -0700 (PDT) Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com. [148.163.156.1]) by mx.google.com with ESMTPS id 15si478763qky.264.2017.10.17.01.08.19 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Oct 2017 01:08:19 -0700 (PDT) Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v9H87vMh049489 for ; Tue, 17 Oct 2017 04:08:18 -0400 Received: from e06smtp10.uk.ibm.com (e06smtp10.uk.ibm.com [195.75.94.106]) by mx0a-001b2d01.pphosted.com with ESMTP id 2dnc6emfme-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 17 Oct 2017 04:08:18 -0400 Received: from localhost by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 17 Oct 2017 09:08:16 +0100 Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v9H88B9b26542302 for ; Tue, 17 Oct 2017 08:08:12 GMT Received: from d23av02.au.ibm.com (localhost [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id v9H882GS010405 for ; Tue, 17 Oct 2017 19:08:02 +1100 Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> From: Anshuman Khandual Date: Tue, 17 Oct 2017 13:38:07 +0530 MIME-Version: 1.0 In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Message-Id: <66a3f340-ff44-efad-48ad-a95554938a29@linux.vnet.ibm.com> Sender: owner-linux-mm@kvack.org List-ID: To: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org On 10/16/2017 02:49 PM, changbin.du@intel.com wrote: > From: Changbin Du > > This patch introduced 4 new interfaces to allocate a prepared > transparent huge page. > - alloc_transhuge_page_vma > - alloc_transhuge_page_nodemask > - alloc_transhuge_page_node > - alloc_transhuge_page > If we are trying to match HugeTLB helpers, then it should have format something like alloc_transhugepage_xxx instead of alloc_transhuge_page_XXX. But I think its okay. > The aim is to remove duplicated code and simplify transparent > huge page allocation. These are similar to alloc_hugepage_xxx > which are for hugetlbfs pages. This patch does below changes: > - define alloc_transhuge_page_xxx interfaces > - apply them to all existing code > - declare prep_transhuge_page as static since no others use it > - remove alloc_hugepage_vma definition since it no longer has users > > Signed-off-by: Changbin Du > --- > include/linux/gfp.h | 4 ---- > include/linux/huge_mm.h | 13 ++++++++++++- > include/linux/migrate.h | 14 +++++--------- > mm/huge_memory.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- > mm/khugepaged.c | 11 ++--------- > mm/mempolicy.c | 10 +++------- > mm/migrate.c | 12 ++++-------- > mm/shmem.c | 6 ++---- > 8 files changed, 71 insertions(+), 49 deletions(-) > > diff --git a/include/linux/gfp.h b/include/linux/gfp.h > index f780718..855c72e 100644 > --- a/include/linux/gfp.h > +++ b/include/linux/gfp.h > @@ -507,15 +507,11 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) > extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, > struct vm_area_struct *vma, unsigned long addr, > int node, bool hugepage); > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > - alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) > #else > #define alloc_pages(gfp_mask, order) \ > alloc_pages_node(numa_node_id(), gfp_mask, order) > #define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ > alloc_pages(gfp_mask, order) > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > - alloc_pages(gfp_mask, order) > #endif > #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) > #define alloc_page_vma(gfp_mask, vma, addr) \ > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 14bc21c..1dd2c33 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > unsigned long flags); > > -extern void prep_transhuge_page(struct page *page); > extern void free_transhuge_page(struct page *page); > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr); > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask); Would not they require 'extern' here ? > + > +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gfp_mask) > +{ > + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); > +} > + > +struct page *alloc_transhuge_page(gfp_t gfp_mask); > + > bool can_split_huge_page(struct page *page, int *pextra_pins); > int split_huge_page_to_list(struct page *page, struct list_head *list); > static inline int split_huge_page(struct page *page) > diff --git a/include/linux/migrate.h b/include/linux/migrate.h > index 643c7ae..70a00f3 100644 > --- a/include/linux/migrate.h > +++ b/include/linux/migrate.h > @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct page *page, > return alloc_huge_page_nodemask(page_hstate(compound_head(page)), > preferred_nid, nodemask); > > - if (thp_migration_supported() && PageTransHuge(page)) { > - order = HPAGE_PMD_ORDER; > - gfp_mask |= GFP_TRANSHUGE; > - } > - > if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) > gfp_mask |= __GFP_HIGHMEM; > > - new_page = __alloc_pages_nodemask(gfp_mask, order, > + if (thp_migration_supported() && PageTransHuge(page)) > + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, > + preferred_nid, nodemask); > + else > + return __alloc_pages_nodemask(gfp_mask, order, > preferred_nid, nodemask); > - > - if (new_page && PageTransHuge(page)) > - prep_transhuge_page(new_page); This makes sense, calling prep_transhuge_page() inside the function alloc_transhuge_page_nodemask() is better I guess. > > return new_page; > } > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index 269b5df..e267488 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(struct page *page) > return (struct list_head *)&page[2].mapping; > } > > -void prep_transhuge_page(struct page *page) > +static void prep_transhuge_page(struct page *page) Right. It wont be used outside huge page allocation context and you have already mentioned about it. > { > /* > * we use page->mapping and page->indexlru in second tail page > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > } > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr) > +{ > + struct page *page; > + > + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + vma, addr, numa_node_id(), true); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} __GFP_COMP and HPAGE_PMD_ORDER are the minimum flags which will be used for huge page allocation and preparation. Any thing else depending upon the context will be passed by the caller. Makes sense. > + > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask) > +{ > + struct page *page; > + > + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + preferred_nid, nmask); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + Same here. > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > +{ > + struct page *page; > + > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); You expect the caller to provide __GFP_COMP, why ? You are anyways providing it later. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f198.google.com (mail-wr0-f198.google.com [209.85.128.198]) by kanga.kvack.org (Postfix) with ESMTP id 1641C6B0253 for ; Tue, 17 Oct 2017 04:37:10 -0400 (EDT) Received: by mail-wr0-f198.google.com with SMTP id j14so473237wre.4 for ; Tue, 17 Oct 2017 01:37:10 -0700 (PDT) Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com. [148.163.158.5]) by mx.google.com with ESMTPS id 92si7140856wrn.293.2017.10.17.01.37.08 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Oct 2017 01:37:08 -0700 (PDT) Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v9H8Yuxp104302 for ; Tue, 17 Oct 2017 04:37:07 -0400 Received: from e06smtp15.uk.ibm.com (e06smtp15.uk.ibm.com [195.75.94.111]) by mx0a-001b2d01.pphosted.com with ESMTP id 2dnajgsj6s-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 17 Oct 2017 04:37:06 -0400 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 17 Oct 2017 09:37:05 +0100 Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v9H8b18t27066400 for ; Tue, 17 Oct 2017 08:37:02 GMT Received: from d23av02.au.ibm.com (localhost [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id v9H8apwh020979 for ; Tue, 17 Oct 2017 19:36:52 +1100 Subject: Re: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-3-git-send-email-changbin.du@intel.com> From: Anshuman Khandual Date: Tue, 17 Oct 2017 14:06:58 +0530 MIME-Version: 1.0 In-Reply-To: <1508145557-9944-3-git-send-email-changbin.du@intel.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Message-Id: <4911ff99-ac77-0344-8696-a15ca9f3e763@linux.vnet.ibm.com> Sender: owner-linux-mm@kvack.org List-ID: To: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org On 10/16/2017 02:49 PM, changbin.du@intel.com wrote: > From: Changbin Du > > The current name free_{huge,transhuge}_page are paired with > alloc_{huge,transhuge}_page functions, but the actual page free > function is still free_page() which will indirectly call > free_{huge,transhuge}_page. So this patch removes this confusion > by renaming all the compound page dtors. > > Signed-off-by: Changbin Du > --- > Documentation/vm/hugetlbfs_reserv.txt | 4 ++-- > include/linux/huge_mm.h | 2 +- > include/linux/hugetlb.h | 2 +- > include/linux/mm.h | 8 ++++---- > mm/huge_memory.c | 4 ++-- > mm/hugetlb.c | 14 +++++++------- > mm/page_alloc.c | 10 +++++----- > mm/swap.c | 2 +- > mm/userfaultfd.c | 2 +- > 9 files changed, 24 insertions(+), 24 deletions(-) > > diff --git a/Documentation/vm/hugetlbfs_reserv.txt b/Documentation/vm/hugetlbfs_reserv.txt > index 9aca09a..b3ffa3e 100644 > --- a/Documentation/vm/hugetlbfs_reserv.txt > +++ b/Documentation/vm/hugetlbfs_reserv.txt > @@ -238,7 +238,7 @@ to the global reservation count (resv_huge_pages). > > Freeing Huge Pages > ------------------ > -Huge page freeing is performed by the routine free_huge_page(). This routine > +Huge page freeing is performed by the routine huge_page_dtor(). This routine > is the destructor for hugetlbfs compound pages. As a result, it is only > passed a pointer to the page struct. When a huge page is freed, reservation > accounting may need to be performed. This would be the case if the page was > @@ -468,7 +468,7 @@ However, there are several instances where errors are encountered after a huge > page is allocated but before it is instantiated. In this case, the page > allocation has consumed the reservation and made the appropriate subpool, > reservation map and global count adjustments. If the page is freed at this > -time (before instantiation and clearing of PagePrivate), then free_huge_page > +time (before instantiation and clearing of PagePrivate), then huge_page_dtor > will increment the global reservation count. However, the reservation map > indicates the reservation was consumed. This resulting inconsistent state > will cause the 'leak' of a reserved huge page. The global reserve count will > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 1dd2c33..40ae3058 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -130,7 +130,7 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > unsigned long flags); > > -extern void free_transhuge_page(struct page *page); > +extern void transhuge_page_dtor(struct page *page); > > struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > struct vm_area_struct *vma, unsigned long addr); > diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h > index 8bbbd37..24492c5 100644 > --- a/include/linux/hugetlb.h > +++ b/include/linux/hugetlb.h > @@ -118,7 +118,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, > long freed); > bool isolate_huge_page(struct page *page, struct list_head *list); > void putback_active_hugepage(struct page *page); > -void free_huge_page(struct page *page); > +void huge_page_dtor(struct page *page); > void hugetlb_fix_reserve_counts(struct inode *inode); > extern struct mutex *hugetlb_fault_mutex_table; > u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 065d99d..adfa906 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -616,7 +616,7 @@ void split_page(struct page *page, unsigned int order); > * prototype for that function and accessor functions. > * These are _only_ valid on the head of a compound page. > */ > -typedef void compound_page_dtor(struct page *); > +typedef void compound_page_dtor_t(struct page *); Why changing this ? I understand _t kind of specifies it more like a type def but this patch is just to rename the compound page destructor functions. Not sure we should change datatype here as well in this patch. > > /* Keep the enum in sync with compound_page_dtors array in mm/page_alloc.c */ > enum compound_dtor_id { > @@ -630,7 +630,7 @@ enum compound_dtor_id { > #endif > NR_COMPOUND_DTORS, > }; > -extern compound_page_dtor * const compound_page_dtors[]; > +extern compound_page_dtor_t * const compound_page_dtors[]; > > static inline void set_compound_page_dtor(struct page *page, > enum compound_dtor_id compound_dtor) > @@ -639,7 +639,7 @@ static inline void set_compound_page_dtor(struct page *page, > page[1].compound_dtor = compound_dtor; > } > > -static inline compound_page_dtor *get_compound_page_dtor(struct page *page) > +static inline compound_page_dtor_t *get_compound_page_dtor(struct page *page) Which is adding these kind of changes to the patch without having a corresponding description in the commit message. > { > VM_BUG_ON_PAGE(page[1].compound_dtor >= NR_COMPOUND_DTORS, page); > return compound_page_dtors[page[1].compound_dtor]; > @@ -657,7 +657,7 @@ static inline void set_compound_order(struct page *page, unsigned int order) > page[1].compound_order = order; > } > > -void free_compound_page(struct page *page); > +void compound_page_dtor(struct page *page); > > #ifdef CONFIG_MMU > /* > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index e267488..a01125b 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -2717,7 +2717,7 @@ fail: if (mapping) > return ret; > } > > -void free_transhuge_page(struct page *page) > +void transhuge_page_dtor(struct page *page) > { > struct pglist_data *pgdata = NODE_DATA(page_to_nid(page)); > unsigned long flags; > @@ -2728,7 +2728,7 @@ void free_transhuge_page(struct page *page) > list_del(page_deferred_list(page)); > } > spin_unlock_irqrestore(&pgdata->split_queue_lock, flags); > - free_compound_page(page); > + compound_page_dtor(page); > } > > void deferred_split_huge_page(struct page *page) > diff --git a/mm/hugetlb.c b/mm/hugetlb.c > index 424b0ef..1af2c4e7 100644 > --- a/mm/hugetlb.c > +++ b/mm/hugetlb.c > @@ -1250,7 +1250,7 @@ static void clear_page_huge_active(struct page *page) > ClearPagePrivate(&page[1]); > } > > -void free_huge_page(struct page *page) > +void huge_page_dtor(struct page *page) > { > /* > * Can't pass hstate in here because it is called from the > @@ -1363,7 +1363,7 @@ int PageHeadHuge(struct page *page_head) > if (!PageHead(page_head)) > return 0; > > - return get_compound_page_dtor(page_head) == free_huge_page; > + return get_compound_page_dtor(page_head) == huge_page_dtor; > } > > pgoff_t __basepage_index(struct page *page) > @@ -1932,11 +1932,11 @@ static long vma_add_reservation(struct hstate *h, > * specific error paths, a huge page was allocated (via alloc_huge_page) > * and is about to be freed. If a reservation for the page existed, > * alloc_huge_page would have consumed the reservation and set PagePrivate > - * in the newly allocated page. When the page is freed via free_huge_page, > + * in the newly allocated page. When the page is freed via huge_page_dtor, > * the global reservation count will be incremented if PagePrivate is set. > - * However, free_huge_page can not adjust the reserve map. Adjust the > + * However, huge_page_dtor can not adjust the reserve map. Adjust the > * reserve map here to be consistent with global reserve count adjustments > - * to be made by free_huge_page. > + * to be made by huge_page_dtor. > */ > static void restore_reserve_on_error(struct hstate *h, > struct vm_area_struct *vma, unsigned long address, > @@ -1950,7 +1950,7 @@ static void restore_reserve_on_error(struct hstate *h, > * Rare out of memory condition in reserve map > * manipulation. Clear PagePrivate so that > * global reserve count will not be incremented > - * by free_huge_page. This will make it appear > + * by huge_page_dtor. This will make it appear > * as though the reservation for this page was > * consumed. This may prevent the task from > * faulting in the page at a later time. This > @@ -2304,7 +2304,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, > while (count > persistent_huge_pages(h)) { > /* > * If this allocation races such that we no longer need the > - * page, free_huge_page will handle it by freeing the page > + * page, huge_page_dtor will handle it by freeing the page > * and reducing the surplus. > */ > spin_unlock(&hugetlb_lock); > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > index 77e4d3c..b31205c 100644 > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -248,14 +248,14 @@ char * const migratetype_names[MIGRATE_TYPES] = { > #endif > }; > > -compound_page_dtor * const compound_page_dtors[] = { > +compound_page_dtor_t * const compound_page_dtors[] = { Adding this chunk as well. > NULL, > - free_compound_page, > + compound_page_dtor, > #ifdef CONFIG_HUGETLB_PAGE > - free_huge_page, > + huge_page_dtor, > #endif > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - free_transhuge_page, > + transhuge_page_dtor, > #endif > }; Having *dtor* in the destructor functions for the huge pages (all of them) actually makes sense. It wont be confused with a lot other free_* functions and some of them dealing with THP/HugeTLB as well. > > @@ -586,7 +586,7 @@ static void bad_page(struct page *page, const char *reason, > * This usage means that zero-order pages may not be compound. > */ > > -void free_compound_page(struct page *page) > +void compound_page_dtor(struct page *page) > { > __free_pages_ok(page, compound_order(page)); > } > diff --git a/mm/swap.c b/mm/swap.c > index a77d68f..8f98caf 100644 > --- a/mm/swap.c > +++ b/mm/swap.c > @@ -81,7 +81,7 @@ static void __put_single_page(struct page *page) > > static void __put_compound_page(struct page *page) > { > - compound_page_dtor *dtor; > + compound_page_dtor_t *dtor; If the typedef change needs to be retained then the commit message must include a line. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f70.google.com (mail-pg0-f70.google.com [74.125.83.70]) by kanga.kvack.org (Postfix) with ESMTP id 977166B0038 for ; Tue, 17 Oct 2017 05:23:30 -0400 (EDT) Received: by mail-pg0-f70.google.com with SMTP id g6so1077963pgn.11 for ; Tue, 17 Oct 2017 02:23:30 -0700 (PDT) Received: from mga05.intel.com (mga05.intel.com. [192.55.52.43]) by mx.google.com with ESMTPS id u3si5939811plm.546.2017.10.17.02.23.29 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Oct 2017 02:23:29 -0700 (PDT) Date: Tue, 17 Oct 2017 17:16:39 +0800 From: "Du, Changbin" Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171017091638.GA7748@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> <66a3f340-ff44-efad-48ad-a95554938a29@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="RnlQjJ0d97Da+TV1" Content-Disposition: inline In-Reply-To: <66a3f340-ff44-efad-48ad-a95554938a29@linux.vnet.ibm.com> Sender: owner-linux-mm@kvack.org List-ID: To: Anshuman Khandual Cc: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org --RnlQjJ0d97Da+TV1 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi Khandual, Thanks for your review. On Tue, Oct 17, 2017 at 01:38:07PM +0530, Anshuman Khandual wrote: > On 10/16/2017 02:49 PM, changbin.du@intel.com wrote: > > From: Changbin Du > >=20 > > This patch introduced 4 new interfaces to allocate a prepared > > transparent huge page. > > - alloc_transhuge_page_vma > > - alloc_transhuge_page_nodemask > > - alloc_transhuge_page_node > > - alloc_transhuge_page > >=20 >=20 > If we are trying to match HugeTLB helpers, then it should have > format something like alloc_transhugepage_xxx instead of > alloc_transhuge_page_XXX. But I think its okay. > HugeTLB helpers are something like alloc_huge_page, so I think alloc_transhuge_page match it. And existing names already have *transhuge_page* style. > > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > > index 14bc21c..1dd2c33 100644 > > --- a/include/linux/huge_mm.h > > +++ b/include/linux/huge_mm.h > > @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct = file *filp, > > unsigned long addr, unsigned long len, unsigned long pgoff, > > unsigned long flags); > > =20 > > -extern void prep_transhuge_page(struct page *page); > > extern void free_transhuge_page(struct page *page); > > =20 > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > > + struct vm_area_struct *vma, unsigned long addr); > > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > > + int preferred_nid, nodemask_t *nmask); >=20 > Would not they require 'extern' here ? > Need or not, function declaration are implicitly 'extern'. I will add it to align with existing code. > > + > > +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gf= p_mask) > > +{ > > + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); > > +} > > + > > +struct page *alloc_transhuge_page(gfp_t gfp_mask); > > + > > bool can_split_huge_page(struct page *page, int *pextra_pins); > > int split_huge_page_to_list(struct page *page, struct list_head *list); > > static inline int split_huge_page(struct page *page) > > diff --git a/include/linux/migrate.h b/include/linux/migrate.h > > index 643c7ae..70a00f3 100644 > > --- a/include/linux/migrate.h > > +++ b/include/linux/migrate.h > > @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct= page *page, > > return alloc_huge_page_nodemask(page_hstate(compound_head(page)), > > preferred_nid, nodemask); > > =20 > > - if (thp_migration_supported() && PageTransHuge(page)) { > > - order =3D HPAGE_PMD_ORDER; > > - gfp_mask |=3D GFP_TRANSHUGE; > > - } > > - > > if (PageHighMem(page) || (zone_idx(page_zone(page)) =3D=3D ZONE_MOVAB= LE)) > > gfp_mask |=3D __GFP_HIGHMEM; > > =20 > > - new_page =3D __alloc_pages_nodemask(gfp_mask, order, > > + if (thp_migration_supported() && PageTransHuge(page)) > > + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, > > + preferred_nid, nodemask); > > + else > > + return __alloc_pages_nodemask(gfp_mask, order, > > preferred_nid, nodemask); > > - > > - if (new_page && PageTransHuge(page)) > > - prep_transhuge_page(new_page); >=20 > This makes sense, calling prep_transhuge_page() inside the > function alloc_transhuge_page_nodemask() is better I guess. >=20 > > =20 > > return new_page; > > } > > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > > index 269b5df..e267488 100644 > > --- a/mm/huge_memory.c > > +++ b/mm/huge_memory.c > > @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(= struct page *page) > > return (struct list_head *)&page[2].mapping; > > } > > =20 > > -void prep_transhuge_page(struct page *page) > > +static void prep_transhuge_page(struct page *page) >=20 > Right. It wont be used outside huge page allocation context and > you have already mentioned about it. >=20 > > { > > /* > > * we use page->mapping and page->indexlru in second tail page > > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > > } > > =20 > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > > + struct vm_area_struct *vma, unsigned long addr) > > +{ > > + struct page *page; > > + > > + page =3D alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > > + vma, addr, numa_node_id(), true); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} >=20 > __GFP_COMP and HPAGE_PMD_ORDER are the minimum flags which will be used > for huge page allocation and preparation. Any thing else depending upon > the context will be passed by the caller. Makes sense. >=20 yes, thanks. > > + > > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > > + int preferred_nid, nodemask_t *nmask) > > +{ > > + struct page *page; > > + > > + page =3D __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDE= R, > > + preferred_nid, nmask); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + >=20 > Same here. >=20 > > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > > +{ > > + struct page *page; > > + > > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); >=20 > You expect the caller to provide __GFP_COMP, why ? You are > anyways providing it later. >=20 oops, I forgot to update this line. Will remove it. Thanks for figuring it = out. --=20 Thanks, Changbin Du --RnlQjJ0d97Da+TV1 Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJZ5cp2AAoJEAanuZwLnPNUnc4IAI8JihFynL2P5Lzy2dzcSg4B 2evr1cmQ8vmf6TKygDpzg+uo2Q0wMXznXo4rgCszf0iH1LwQzSasi/iNcK0WUSeE l1/fUzouDomNCaAVu7QA0Dc4ov710Zli8Yj1PTRH2VnHrG7qeiAu0OsimX06Wh3S y6ZHkz9PRw7QmVZWm05MENjJVRsAHWIZ9ZxcBnxvrO2T8S02HnFU9NOM65r8LnA+ HipRnmOERQz0ZJHdeC4/LyYGaD2aCLCsOY9jDoNHBnVL08sZ3bnpE1/RtlFLLFz0 G681odJDKMFSIxURYmfL51fXigENsTSBAv9Z5j9M63ahL6BKwjcOh1UVoESzmS4= =EAaI -----END PGP SIGNATURE----- --RnlQjJ0d97Da+TV1-- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f72.google.com (mail-pg0-f72.google.com [74.125.83.72]) by kanga.kvack.org (Postfix) with ESMTP id C068D6B0038 for ; Tue, 17 Oct 2017 05:28:23 -0400 (EDT) Received: by mail-pg0-f72.google.com with SMTP id s2so1077234pge.19 for ; Tue, 17 Oct 2017 02:28:23 -0700 (PDT) Received: from mga06.intel.com (mga06.intel.com. [134.134.136.31]) by mx.google.com with ESMTPS id g71si5203255pgc.308.2017.10.17.02.28.22 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Oct 2017 02:28:22 -0700 (PDT) Date: Tue, 17 Oct 2017 17:21:32 +0800 From: "Du, Changbin" Subject: Re: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Message-ID: <20171017092131.GB7748@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-3-git-send-email-changbin.du@intel.com> <4911ff99-ac77-0344-8696-a15ca9f3e763@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="mojUlQ0s9EVzWg2t" Content-Disposition: inline In-Reply-To: <4911ff99-ac77-0344-8696-a15ca9f3e763@linux.vnet.ibm.com> Sender: owner-linux-mm@kvack.org List-ID: To: Anshuman Khandual Cc: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org --mojUlQ0s9EVzWg2t Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi Khandual, > > long freed); > > bool isolate_huge_page(struct page *page, struct list_head *list); > > void putback_active_hugepage(struct page *page); > > -void free_huge_page(struct page *page); > > +void huge_page_dtor(struct page *page); > > void hugetlb_fix_reserve_counts(struct inode *inode); > > extern struct mutex *hugetlb_fault_mutex_table; > > u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, > > diff --git a/include/linux/mm.h b/include/linux/mm.h > > index 065d99d..adfa906 100644 > > --- a/include/linux/mm.h > > +++ b/include/linux/mm.h > > @@ -616,7 +616,7 @@ void split_page(struct page *page, unsigned int ord= er); > > * prototype for that function and accessor functions. > > * These are _only_ valid on the head of a compound page. > > */ > > -typedef void compound_page_dtor(struct page *); > > +typedef void compound_page_dtor_t(struct page *); >=20 > Why changing this ? I understand _t kind of specifies it more > like a type def but this patch is just to rename the compound > page destructor functions. Not sure we should change datatype > here as well in this patch. > It is because of name conflict. I think you already get it per below commen= ts. I will describe it in commit message. > > =20 > > /* Keep the enum in sync with compound_page_dtors array in mm/page_all= oc.c */ > > enum compound_dtor_id { > > @@ -630,7 +630,7 @@ enum compound_dtor_id { > > #endif > > NR_COMPOUND_DTORS, > > }; > > -extern compound_page_dtor * const compound_page_dtors[]; > > +extern compound_page_dtor_t * const compound_page_dtors[]; > > =20 > > static inline void set_compound_page_dtor(struct page *page, > > enum compound_dtor_id compound_dtor) > > @@ -639,7 +639,7 @@ static inline void set_compound_page_dtor(struct pa= ge *page, > > page[1].compound_dtor =3D compound_dtor; > > } > > =20 > > -static inline compound_page_dtor *get_compound_page_dtor(struct page *= page) > > +static inline compound_page_dtor_t *get_compound_page_dtor(struct page= *page) >=20 > Which is adding these kind of changes to the patch without > having a corresponding description in the commit message. >=20 > > { > > VM_BUG_ON_PAGE(page[1].compound_dtor >=3D NR_COMPOUND_DTORS, page); > > return compound_page_dtors[page[1].compound_dtor]; > > @@ -657,7 +657,7 @@ static inline void set_compound_order(struct page *= page, unsigned int order) > > page[1].compound_order =3D order; > > } > > =20 > > -void free_compound_page(struct page *page); > > +void compound_page_dtor(struct page *page); > > =20 > > #ifdef CONFIG_MMU > > /* > > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > > index e267488..a01125b 100644 > > --- a/mm/huge_memory.c > > +++ b/mm/huge_memory.c > > @@ -2717,7 +2717,7 @@ fail: if (mapping) > > return ret; > > } > > =20 > > -void free_transhuge_page(struct page *page) > > +void transhuge_page_dtor(struct page *page) > > { > > struct pglist_data *pgdata =3D NODE_DATA(page_to_nid(page)); > > unsigned long flags; > > @@ -2728,7 +2728,7 @@ void free_transhuge_page(struct page *page) > > list_del(page_deferred_list(page)); > > } > > spin_unlock_irqrestore(&pgdata->split_queue_lock, flags); > > - free_compound_page(page); > > + compound_page_dtor(page); > > } > > =20 > > void deferred_split_huge_page(struct page *page) > > diff --git a/mm/hugetlb.c b/mm/hugetlb.c > > index 424b0ef..1af2c4e7 100644 > > --- a/mm/hugetlb.c > > +++ b/mm/hugetlb.c > > @@ -1250,7 +1250,7 @@ static void clear_page_huge_active(struct page *p= age) > > ClearPagePrivate(&page[1]); > > } > > =20 > > -void free_huge_page(struct page *page) > > +void huge_page_dtor(struct page *page) > > { > > /* > > * Can't pass hstate in here because it is called from the > > @@ -1363,7 +1363,7 @@ int PageHeadHuge(struct page *page_head) > > if (!PageHead(page_head)) > > return 0; > > =20 > > - return get_compound_page_dtor(page_head) =3D=3D free_huge_page; > > + return get_compound_page_dtor(page_head) =3D=3D huge_page_dtor; > > } > > =20 > > pgoff_t __basepage_index(struct page *page) > > @@ -1932,11 +1932,11 @@ static long vma_add_reservation(struct hstate *= h, > > * specific error paths, a huge page was allocated (via alloc_huge_pag= e) > > * and is about to be freed. If a reservation for the page existed, > > * alloc_huge_page would have consumed the reservation and set PagePri= vate > > - * in the newly allocated page. When the page is freed via free_huge_= page, > > + * in the newly allocated page. When the page is freed via huge_page_= dtor, > > * the global reservation count will be incremented if PagePrivate is = set. > > - * However, free_huge_page can not adjust the reserve map. Adjust the > > + * However, huge_page_dtor can not adjust the reserve map. Adjust the > > * reserve map here to be consistent with global reserve count adjustm= ents > > - * to be made by free_huge_page. > > + * to be made by huge_page_dtor. > > */ > > static void restore_reserve_on_error(struct hstate *h, > > struct vm_area_struct *vma, unsigned long address, > > @@ -1950,7 +1950,7 @@ static void restore_reserve_on_error(struct hstat= e *h, > > * Rare out of memory condition in reserve map > > * manipulation. Clear PagePrivate so that > > * global reserve count will not be incremented > > - * by free_huge_page. This will make it appear > > + * by huge_page_dtor. This will make it appear > > * as though the reservation for this page was > > * consumed. This may prevent the task from > > * faulting in the page at a later time. This > > @@ -2304,7 +2304,7 @@ static unsigned long set_max_huge_pages(struct hs= tate *h, unsigned long count, > > while (count > persistent_huge_pages(h)) { > > /* > > * If this allocation races such that we no longer need the > > - * page, free_huge_page will handle it by freeing the page > > + * page, huge_page_dtor will handle it by freeing the page > > * and reducing the surplus. > > */ > > spin_unlock(&hugetlb_lock); > > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > > index 77e4d3c..b31205c 100644 > > --- a/mm/page_alloc.c > > +++ b/mm/page_alloc.c > > @@ -248,14 +248,14 @@ char * const migratetype_names[MIGRATE_TYPES] =3D= { > > #endif > > }; > > =20 > > -compound_page_dtor * const compound_page_dtors[] =3D { > > +compound_page_dtor_t * const compound_page_dtors[] =3D { >=20 > Adding this chunk as well. >=20 Sure. > > NULL, > > - free_compound_page, > > + compound_page_dtor, > > #ifdef CONFIG_HUGETLB_PAGE > > - free_huge_page, > > + huge_page_dtor, > > #endif > > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > > - free_transhuge_page, > > + transhuge_page_dtor, > > #endif > > }; >=20 > Having *dtor* in the destructor functions for the huge pages > (all of them) actually makes sense. It wont be confused with > a lot other free_* functions and some of them dealing with > THP/HugeTLB as well. >=20 echo! > > =20 > > @@ -586,7 +586,7 @@ static void bad_page(struct page *page, const char = *reason, > > * This usage means that zero-order pages may not be compound. > > */ > > =20 > > -void free_compound_page(struct page *page) > > +void compound_page_dtor(struct page *page) > > { > > __free_pages_ok(page, compound_order(page)); > > } > > diff --git a/mm/swap.c b/mm/swap.c > > index a77d68f..8f98caf 100644 > > --- a/mm/swap.c > > +++ b/mm/swap.c > > @@ -81,7 +81,7 @@ static void __put_single_page(struct page *page) > > =20 > > static void __put_compound_page(struct page *page) > > { > > - compound_page_dtor *dtor; > > + compound_page_dtor_t *dtor; >=20 > If the typedef change needs to be retained then the commit message > must include a line. >=20 will do it. Thanks. > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majordomo@kvack.org. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: email@kvack.org --=20 Thanks, Changbin Du --mojUlQ0s9EVzWg2t Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJZ5cubAAoJEAanuZwLnPNUyZcH/3daudI4SJeVAmJ1D0K4oPTz m5y4ZiKSC4D3aL8TlgyAKPtqxndHseiKpsVIJ72lEbI+AZQiIPyrg49kO58erk72 vwsxuE6cyufEPZj6X3DhjuHyQXuseVozwr/UAkfX+P7jyaOho5QvRwEID2wWDv5P PYTuA284IMRxt0qA3AZEsrzse616Ynu5wh+1mtLlcPS1qhisS4OoR5OpMZafp5e8 hQmY//SytrqFYecZLeKiHf7oDjly6ncSLqZD8NFtfJGioZDN9CPg8fGQb3yekiep u4WIlW9Cqo8j07MTw+vTXNLGSjBaH5zGJkUy9QUc3X85LOBLYW2i54KolG5bLGk= =9dRe -----END PGP SIGNATURE----- --mojUlQ0s9EVzWg2t-- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f70.google.com (mail-pg0-f70.google.com [74.125.83.70]) by kanga.kvack.org (Postfix) with ESMTP id 80D966B0038 for ; Tue, 17 Oct 2017 06:20:56 -0400 (EDT) Received: by mail-pg0-f70.google.com with SMTP id r18so1193491pgu.9 for ; Tue, 17 Oct 2017 03:20:56 -0700 (PDT) Received: from mx2.suse.de (mx2.suse.de. [195.135.220.15]) by mx.google.com with ESMTPS id 85si4608402pfz.417.2017.10.17.03.20.54 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 17 Oct 2017 03:20:55 -0700 (PDT) Date: Tue, 17 Oct 2017 12:20:52 +0200 From: Michal Hocko Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> Sender: owner-linux-mm@kvack.org List-ID: To: changbin.du@intel.com Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org [CC Kirill] On Mon 16-10-17 17:19:16, changbin.du@intel.com wrote: > From: Changbin Du > > This patch introduced 4 new interfaces to allocate a prepared > transparent huge page. > - alloc_transhuge_page_vma > - alloc_transhuge_page_nodemask > - alloc_transhuge_page_node > - alloc_transhuge_page > > The aim is to remove duplicated code and simplify transparent > huge page allocation. These are similar to alloc_hugepage_xxx > which are for hugetlbfs pages. This patch does below changes: > - define alloc_transhuge_page_xxx interfaces > - apply them to all existing code > - declare prep_transhuge_page as static since no others use it > - remove alloc_hugepage_vma definition since it no longer has users So what exactly is the advantage of the new API? The diffstat doesn't sound very convincing to me. > Signed-off-by: Changbin Du > --- > include/linux/gfp.h | 4 ---- > include/linux/huge_mm.h | 13 ++++++++++++- > include/linux/migrate.h | 14 +++++--------- > mm/huge_memory.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- > mm/khugepaged.c | 11 ++--------- > mm/mempolicy.c | 10 +++------- > mm/migrate.c | 12 ++++-------- > mm/shmem.c | 6 ++---- > 8 files changed, 71 insertions(+), 49 deletions(-) > > diff --git a/include/linux/gfp.h b/include/linux/gfp.h > index f780718..855c72e 100644 > --- a/include/linux/gfp.h > +++ b/include/linux/gfp.h > @@ -507,15 +507,11 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) > extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, > struct vm_area_struct *vma, unsigned long addr, > int node, bool hugepage); > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > - alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) > #else > #define alloc_pages(gfp_mask, order) \ > alloc_pages_node(numa_node_id(), gfp_mask, order) > #define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ > alloc_pages(gfp_mask, order) > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > - alloc_pages(gfp_mask, order) > #endif > #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) > #define alloc_page_vma(gfp_mask, vma, addr) \ > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 14bc21c..1dd2c33 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > unsigned long flags); > > -extern void prep_transhuge_page(struct page *page); > extern void free_transhuge_page(struct page *page); > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr); > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask); > + > +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gfp_mask) > +{ > + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); > +} > + > +struct page *alloc_transhuge_page(gfp_t gfp_mask); > + > bool can_split_huge_page(struct page *page, int *pextra_pins); > int split_huge_page_to_list(struct page *page, struct list_head *list); > static inline int split_huge_page(struct page *page) > diff --git a/include/linux/migrate.h b/include/linux/migrate.h > index 643c7ae..70a00f3 100644 > --- a/include/linux/migrate.h > +++ b/include/linux/migrate.h > @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct page *page, > return alloc_huge_page_nodemask(page_hstate(compound_head(page)), > preferred_nid, nodemask); > > - if (thp_migration_supported() && PageTransHuge(page)) { > - order = HPAGE_PMD_ORDER; > - gfp_mask |= GFP_TRANSHUGE; > - } > - > if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) > gfp_mask |= __GFP_HIGHMEM; > > - new_page = __alloc_pages_nodemask(gfp_mask, order, > + if (thp_migration_supported() && PageTransHuge(page)) > + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, > + preferred_nid, nodemask); > + else > + return __alloc_pages_nodemask(gfp_mask, order, > preferred_nid, nodemask); > - > - if (new_page && PageTransHuge(page)) > - prep_transhuge_page(new_page); > > return new_page; > } > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index 269b5df..e267488 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(struct page *page) > return (struct list_head *)&page[2].mapping; > } > > -void prep_transhuge_page(struct page *page) > +static void prep_transhuge_page(struct page *page) > { > /* > * we use page->mapping and page->indexlru in second tail page > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > } > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr) > +{ > + struct page *page; > + > + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + vma, addr, numa_node_id(), true); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask) > +{ > + struct page *page; > + > + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + preferred_nid, nmask); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > +{ > + struct page *page; > + > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); > + > + page = alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, > loff_t off, unsigned long flags, unsigned long size) > { > @@ -719,12 +758,11 @@ int do_huge_pmd_anonymous_page(struct vm_fault *vmf) > return ret; > } > gfp = alloc_hugepage_direct_gfpmask(vma); > - page = alloc_hugepage_vma(gfp, vma, haddr, HPAGE_PMD_ORDER); > + page = alloc_transhuge_page_vma(gfp, vma, haddr); > if (unlikely(!page)) { > count_vm_event(THP_FAULT_FALLBACK); > return VM_FAULT_FALLBACK; > } > - prep_transhuge_page(page); > return __do_huge_pmd_anonymous_page(vmf, page, gfp); > } > > @@ -1288,13 +1326,11 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) > if (transparent_hugepage_enabled(vma) && > !transparent_hugepage_debug_cow()) { > huge_gfp = alloc_hugepage_direct_gfpmask(vma); > - new_page = alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDER); > + new_page = alloc_transhuge_page_vma(huge_gfp, vma, haddr); > } else > new_page = NULL; > > - if (likely(new_page)) { > - prep_transhuge_page(new_page); > - } else { > + if (unlikely(!new_page)) { > if (!page) { > split_huge_pmd(vma, vmf->pmd, vmf->address); > ret |= VM_FAULT_FALLBACK; > diff --git a/mm/khugepaged.c b/mm/khugepaged.c > index c01f177..d17a694 100644 > --- a/mm/khugepaged.c > +++ b/mm/khugepaged.c > @@ -745,14 +745,13 @@ khugepaged_alloc_page(struct page **hpage, gfp_t gfp, int node) > { > VM_BUG_ON_PAGE(*hpage, *hpage); > > - *hpage = __alloc_pages_node(node, gfp, HPAGE_PMD_ORDER); > + *hpage = alloc_transhuge_page_node(node, gfp); > if (unlikely(!*hpage)) { > count_vm_event(THP_COLLAPSE_ALLOC_FAILED); > *hpage = ERR_PTR(-ENOMEM); > return NULL; > } > > - prep_transhuge_page(*hpage); > count_vm_event(THP_COLLAPSE_ALLOC); > return *hpage; > } > @@ -764,13 +763,7 @@ static int khugepaged_find_target_node(void) > > static inline struct page *alloc_khugepaged_hugepage(void) > { > - struct page *page; > - > - page = alloc_pages(alloc_hugepage_khugepaged_gfpmask(), > - HPAGE_PMD_ORDER); > - if (page) > - prep_transhuge_page(page); > - return page; > + return alloc_transhuge_page(alloc_hugepage_khugepaged_gfpmask()); > } > > static struct page *khugepaged_alloc_hugepage(bool *wait) > diff --git a/mm/mempolicy.c b/mm/mempolicy.c > index a2af6d5..aa24285 100644 > --- a/mm/mempolicy.c > +++ b/mm/mempolicy.c > @@ -949,12 +949,10 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x > else if (thp_migration_supported() && PageTransHuge(page)) { > struct page *thp; > > - thp = alloc_pages_node(node, > - (GFP_TRANSHUGE | __GFP_THISNODE), > - HPAGE_PMD_ORDER); > + thp = alloc_transhuge_page_node(node, > + (GFP_TRANSHUGE | __GFP_THISNODE)); > if (!thp) > return NULL; > - prep_transhuge_page(thp); > return thp; > } else > return __alloc_pages_node(node, GFP_HIGHUSER_MOVABLE | > @@ -1125,11 +1123,9 @@ static struct page *new_page(struct page *page, unsigned long start, int **x) > } else if (thp_migration_supported() && PageTransHuge(page)) { > struct page *thp; > > - thp = alloc_hugepage_vma(GFP_TRANSHUGE, vma, address, > - HPAGE_PMD_ORDER); > + thp = alloc_transhuge_page_vma(GFP_TRANSHUGE, vma, address); > if (!thp) > return NULL; > - prep_transhuge_page(thp); > return thp; > } > /* > diff --git a/mm/migrate.c b/mm/migrate.c > index e00814c..7f0486f 100644 > --- a/mm/migrate.c > +++ b/mm/migrate.c > @@ -1472,12 +1472,10 @@ static struct page *new_page_node(struct page *p, unsigned long private, > else if (thp_migration_supported() && PageTransHuge(p)) { > struct page *thp; > > - thp = alloc_pages_node(pm->node, > - (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM, > - HPAGE_PMD_ORDER); > + thp = alloc_transhuge_page_node(pm->node, > + (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM); > if (!thp) > return NULL; > - prep_transhuge_page(thp); > return thp; > } else > return __alloc_pages_node(pm->node, > @@ -2017,12 +2015,10 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, > if (numamigrate_update_ratelimit(pgdat, HPAGE_PMD_NR)) > goto out_dropref; > > - new_page = alloc_pages_node(node, > - (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE), > - HPAGE_PMD_ORDER); > + new_page = alloc_transhuge_page_node(node, > + (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE)); > if (!new_page) > goto out_fail; > - prep_transhuge_page(new_page); > > isolated = numamigrate_isolate_page(pgdat, page); > if (!isolated) { > diff --git a/mm/shmem.c b/mm/shmem.c > index 07a1d22..52468f7 100644 > --- a/mm/shmem.c > +++ b/mm/shmem.c > @@ -1444,11 +1444,9 @@ static struct page *shmem_alloc_hugepage(gfp_t gfp, > rcu_read_unlock(); > > shmem_pseudo_vma_init(&pvma, info, hindex); > - page = alloc_pages_vma(gfp | __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN, > - HPAGE_PMD_ORDER, &pvma, 0, numa_node_id(), true); > + gfp |= __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN; > + page = alloc_transhuge_page_vma(gfp, &pvma, 0); > shmem_pseudo_vma_destroy(&pvma); > - if (page) > - prep_transhuge_page(page); > return page; > } > > -- > 2.7.4 > > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majordomo@kvack.org. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: email@kvack.org -- Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f69.google.com (mail-pg0-f69.google.com [74.125.83.69]) by kanga.kvack.org (Postfix) with ESMTP id E09256B0038 for ; Tue, 17 Oct 2017 06:22:06 -0400 (EDT) Received: by mail-pg0-f69.google.com with SMTP id k7so1188925pga.8 for ; Tue, 17 Oct 2017 03:22:06 -0700 (PDT) Received: from mx2.suse.de (mx2.suse.de. [195.135.220.15]) by mx.google.com with ESMTPS id z21si1449659plo.160.2017.10.17.03.22.05 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 17 Oct 2017 03:22:05 -0700 (PDT) Date: Tue, 17 Oct 2017 12:22:03 +0200 From: Michal Hocko Subject: Re: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Message-ID: <20171017102203.u2v3p2ivuogu4rk6@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-3-git-send-email-changbin.du@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1508145557-9944-3-git-send-email-changbin.du@intel.com> Sender: owner-linux-mm@kvack.org List-ID: To: changbin.du@intel.com Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org On Mon 16-10-17 17:19:17, changbin.du@intel.com wrote: > From: Changbin Du > > The current name free_{huge,transhuge}_page are paired with > alloc_{huge,transhuge}_page functions, but the actual page free > function is still free_page() which will indirectly call > free_{huge,transhuge}_page. So this patch removes this confusion > by renaming all the compound page dtors. Is this code churn really worth it? > Signed-off-by: Changbin Du > --- > Documentation/vm/hugetlbfs_reserv.txt | 4 ++-- > include/linux/huge_mm.h | 2 +- > include/linux/hugetlb.h | 2 +- > include/linux/mm.h | 8 ++++---- > mm/huge_memory.c | 4 ++-- > mm/hugetlb.c | 14 +++++++------- > mm/page_alloc.c | 10 +++++----- > mm/swap.c | 2 +- > mm/userfaultfd.c | 2 +- > 9 files changed, 24 insertions(+), 24 deletions(-) > > diff --git a/Documentation/vm/hugetlbfs_reserv.txt b/Documentation/vm/hugetlbfs_reserv.txt > index 9aca09a..b3ffa3e 100644 > --- a/Documentation/vm/hugetlbfs_reserv.txt > +++ b/Documentation/vm/hugetlbfs_reserv.txt > @@ -238,7 +238,7 @@ to the global reservation count (resv_huge_pages). > > Freeing Huge Pages > ------------------ > -Huge page freeing is performed by the routine free_huge_page(). This routine > +Huge page freeing is performed by the routine huge_page_dtor(). This routine > is the destructor for hugetlbfs compound pages. As a result, it is only > passed a pointer to the page struct. When a huge page is freed, reservation > accounting may need to be performed. This would be the case if the page was > @@ -468,7 +468,7 @@ However, there are several instances where errors are encountered after a huge > page is allocated but before it is instantiated. In this case, the page > allocation has consumed the reservation and made the appropriate subpool, > reservation map and global count adjustments. If the page is freed at this > -time (before instantiation and clearing of PagePrivate), then free_huge_page > +time (before instantiation and clearing of PagePrivate), then huge_page_dtor > will increment the global reservation count. However, the reservation map > indicates the reservation was consumed. This resulting inconsistent state > will cause the 'leak' of a reserved huge page. The global reserve count will > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 1dd2c33..40ae3058 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -130,7 +130,7 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > unsigned long flags); > > -extern void free_transhuge_page(struct page *page); > +extern void transhuge_page_dtor(struct page *page); > > struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > struct vm_area_struct *vma, unsigned long addr); > diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h > index 8bbbd37..24492c5 100644 > --- a/include/linux/hugetlb.h > +++ b/include/linux/hugetlb.h > @@ -118,7 +118,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, > long freed); > bool isolate_huge_page(struct page *page, struct list_head *list); > void putback_active_hugepage(struct page *page); > -void free_huge_page(struct page *page); > +void huge_page_dtor(struct page *page); > void hugetlb_fix_reserve_counts(struct inode *inode); > extern struct mutex *hugetlb_fault_mutex_table; > u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 065d99d..adfa906 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -616,7 +616,7 @@ void split_page(struct page *page, unsigned int order); > * prototype for that function and accessor functions. > * These are _only_ valid on the head of a compound page. > */ > -typedef void compound_page_dtor(struct page *); > +typedef void compound_page_dtor_t(struct page *); > > /* Keep the enum in sync with compound_page_dtors array in mm/page_alloc.c */ > enum compound_dtor_id { > @@ -630,7 +630,7 @@ enum compound_dtor_id { > #endif > NR_COMPOUND_DTORS, > }; > -extern compound_page_dtor * const compound_page_dtors[]; > +extern compound_page_dtor_t * const compound_page_dtors[]; > > static inline void set_compound_page_dtor(struct page *page, > enum compound_dtor_id compound_dtor) > @@ -639,7 +639,7 @@ static inline void set_compound_page_dtor(struct page *page, > page[1].compound_dtor = compound_dtor; > } > > -static inline compound_page_dtor *get_compound_page_dtor(struct page *page) > +static inline compound_page_dtor_t *get_compound_page_dtor(struct page *page) > { > VM_BUG_ON_PAGE(page[1].compound_dtor >= NR_COMPOUND_DTORS, page); > return compound_page_dtors[page[1].compound_dtor]; > @@ -657,7 +657,7 @@ static inline void set_compound_order(struct page *page, unsigned int order) > page[1].compound_order = order; > } > > -void free_compound_page(struct page *page); > +void compound_page_dtor(struct page *page); > > #ifdef CONFIG_MMU > /* > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index e267488..a01125b 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -2717,7 +2717,7 @@ fail: if (mapping) > return ret; > } > > -void free_transhuge_page(struct page *page) > +void transhuge_page_dtor(struct page *page) > { > struct pglist_data *pgdata = NODE_DATA(page_to_nid(page)); > unsigned long flags; > @@ -2728,7 +2728,7 @@ void free_transhuge_page(struct page *page) > list_del(page_deferred_list(page)); > } > spin_unlock_irqrestore(&pgdata->split_queue_lock, flags); > - free_compound_page(page); > + compound_page_dtor(page); > } > > void deferred_split_huge_page(struct page *page) > diff --git a/mm/hugetlb.c b/mm/hugetlb.c > index 424b0ef..1af2c4e7 100644 > --- a/mm/hugetlb.c > +++ b/mm/hugetlb.c > @@ -1250,7 +1250,7 @@ static void clear_page_huge_active(struct page *page) > ClearPagePrivate(&page[1]); > } > > -void free_huge_page(struct page *page) > +void huge_page_dtor(struct page *page) > { > /* > * Can't pass hstate in here because it is called from the > @@ -1363,7 +1363,7 @@ int PageHeadHuge(struct page *page_head) > if (!PageHead(page_head)) > return 0; > > - return get_compound_page_dtor(page_head) == free_huge_page; > + return get_compound_page_dtor(page_head) == huge_page_dtor; > } > > pgoff_t __basepage_index(struct page *page) > @@ -1932,11 +1932,11 @@ static long vma_add_reservation(struct hstate *h, > * specific error paths, a huge page was allocated (via alloc_huge_page) > * and is about to be freed. If a reservation for the page existed, > * alloc_huge_page would have consumed the reservation and set PagePrivate > - * in the newly allocated page. When the page is freed via free_huge_page, > + * in the newly allocated page. When the page is freed via huge_page_dtor, > * the global reservation count will be incremented if PagePrivate is set. > - * However, free_huge_page can not adjust the reserve map. Adjust the > + * However, huge_page_dtor can not adjust the reserve map. Adjust the > * reserve map here to be consistent with global reserve count adjustments > - * to be made by free_huge_page. > + * to be made by huge_page_dtor. > */ > static void restore_reserve_on_error(struct hstate *h, > struct vm_area_struct *vma, unsigned long address, > @@ -1950,7 +1950,7 @@ static void restore_reserve_on_error(struct hstate *h, > * Rare out of memory condition in reserve map > * manipulation. Clear PagePrivate so that > * global reserve count will not be incremented > - * by free_huge_page. This will make it appear > + * by huge_page_dtor. This will make it appear > * as though the reservation for this page was > * consumed. This may prevent the task from > * faulting in the page at a later time. This > @@ -2304,7 +2304,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, > while (count > persistent_huge_pages(h)) { > /* > * If this allocation races such that we no longer need the > - * page, free_huge_page will handle it by freeing the page > + * page, huge_page_dtor will handle it by freeing the page > * and reducing the surplus. > */ > spin_unlock(&hugetlb_lock); > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > index 77e4d3c..b31205c 100644 > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -248,14 +248,14 @@ char * const migratetype_names[MIGRATE_TYPES] = { > #endif > }; > > -compound_page_dtor * const compound_page_dtors[] = { > +compound_page_dtor_t * const compound_page_dtors[] = { > NULL, > - free_compound_page, > + compound_page_dtor, > #ifdef CONFIG_HUGETLB_PAGE > - free_huge_page, > + huge_page_dtor, > #endif > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - free_transhuge_page, > + transhuge_page_dtor, > #endif > }; > > @@ -586,7 +586,7 @@ static void bad_page(struct page *page, const char *reason, > * This usage means that zero-order pages may not be compound. > */ > > -void free_compound_page(struct page *page) > +void compound_page_dtor(struct page *page) > { > __free_pages_ok(page, compound_order(page)); > } > diff --git a/mm/swap.c b/mm/swap.c > index a77d68f..8f98caf 100644 > --- a/mm/swap.c > +++ b/mm/swap.c > @@ -81,7 +81,7 @@ static void __put_single_page(struct page *page) > > static void __put_compound_page(struct page *page) > { > - compound_page_dtor *dtor; > + compound_page_dtor_t *dtor; > > /* > * __page_cache_release() is supposed to be called for thp, not for > diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c > index 8119270..91d9045 100644 > --- a/mm/userfaultfd.c > +++ b/mm/userfaultfd.c > @@ -323,7 +323,7 @@ static __always_inline ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, > * map of a private mapping, the map was modified to indicate > * the reservation was consumed when the page was allocated. > * We clear the PagePrivate flag now so that the global > - * reserve count will not be incremented in free_huge_page. > + * reserve count will not be incremented in huge_page_dtor. > * The reservation map will still indicate the reservation > * was consumed and possibly prevent later page allocation. > * This is better than leaking a global reservation. If no > -- > 2.7.4 > > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majordomo@kvack.org. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: email@kvack.org -- Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f71.google.com (mail-pg0-f71.google.com [74.125.83.71]) by kanga.kvack.org (Postfix) with ESMTP id 901546B0069 for ; Tue, 17 Oct 2017 06:22:28 -0400 (EDT) Received: by mail-pg0-f71.google.com with SMTP id g6so1189225pgn.11 for ; Tue, 17 Oct 2017 03:22:28 -0700 (PDT) Received: from mx2.suse.de (mx2.suse.de. [195.135.220.15]) by mx.google.com with ESMTPS id h69si5666399pfe.479.2017.10.17.03.22.26 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 17 Oct 2017 03:22:27 -0700 (PDT) Date: Tue, 17 Oct 2017 12:22:24 +0200 From: Michal Hocko Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171017102224.irddxjgigcv7yxlg@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> Sender: owner-linux-mm@kvack.org List-ID: To: changbin.du@intel.com Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, "Kirill A. Shutemov" On Tue 17-10-17 12:20:52, Michal Hocko wrote: > [CC Kirill] now for real > On Mon 16-10-17 17:19:16, changbin.du@intel.com wrote: > > From: Changbin Du > > > > This patch introduced 4 new interfaces to allocate a prepared > > transparent huge page. > > - alloc_transhuge_page_vma > > - alloc_transhuge_page_nodemask > > - alloc_transhuge_page_node > > - alloc_transhuge_page > > > > The aim is to remove duplicated code and simplify transparent > > huge page allocation. These are similar to alloc_hugepage_xxx > > which are for hugetlbfs pages. This patch does below changes: > > - define alloc_transhuge_page_xxx interfaces > > - apply them to all existing code > > - declare prep_transhuge_page as static since no others use it > > - remove alloc_hugepage_vma definition since it no longer has users > > So what exactly is the advantage of the new API? The diffstat doesn't > sound very convincing to me. > > > Signed-off-by: Changbin Du > > --- > > include/linux/gfp.h | 4 ---- > > include/linux/huge_mm.h | 13 ++++++++++++- > > include/linux/migrate.h | 14 +++++--------- > > mm/huge_memory.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- > > mm/khugepaged.c | 11 ++--------- > > mm/mempolicy.c | 10 +++------- > > mm/migrate.c | 12 ++++-------- > > mm/shmem.c | 6 ++---- > > 8 files changed, 71 insertions(+), 49 deletions(-) > > > > diff --git a/include/linux/gfp.h b/include/linux/gfp.h > > index f780718..855c72e 100644 > > --- a/include/linux/gfp.h > > +++ b/include/linux/gfp.h > > @@ -507,15 +507,11 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) > > extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, > > struct vm_area_struct *vma, unsigned long addr, > > int node, bool hugepage); > > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > > - alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) > > #else > > #define alloc_pages(gfp_mask, order) \ > > alloc_pages_node(numa_node_id(), gfp_mask, order) > > #define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ > > alloc_pages(gfp_mask, order) > > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > > - alloc_pages(gfp_mask, order) > > #endif > > #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) > > #define alloc_page_vma(gfp_mask, vma, addr) \ > > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > > index 14bc21c..1dd2c33 100644 > > --- a/include/linux/huge_mm.h > > +++ b/include/linux/huge_mm.h > > @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > > unsigned long addr, unsigned long len, unsigned long pgoff, > > unsigned long flags); > > > > -extern void prep_transhuge_page(struct page *page); > > extern void free_transhuge_page(struct page *page); > > > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > > + struct vm_area_struct *vma, unsigned long addr); > > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > > + int preferred_nid, nodemask_t *nmask); > > + > > +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gfp_mask) > > +{ > > + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); > > +} > > + > > +struct page *alloc_transhuge_page(gfp_t gfp_mask); > > + > > bool can_split_huge_page(struct page *page, int *pextra_pins); > > int split_huge_page_to_list(struct page *page, struct list_head *list); > > static inline int split_huge_page(struct page *page) > > diff --git a/include/linux/migrate.h b/include/linux/migrate.h > > index 643c7ae..70a00f3 100644 > > --- a/include/linux/migrate.h > > +++ b/include/linux/migrate.h > > @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct page *page, > > return alloc_huge_page_nodemask(page_hstate(compound_head(page)), > > preferred_nid, nodemask); > > > > - if (thp_migration_supported() && PageTransHuge(page)) { > > - order = HPAGE_PMD_ORDER; > > - gfp_mask |= GFP_TRANSHUGE; > > - } > > - > > if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) > > gfp_mask |= __GFP_HIGHMEM; > > > > - new_page = __alloc_pages_nodemask(gfp_mask, order, > > + if (thp_migration_supported() && PageTransHuge(page)) > > + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, > > + preferred_nid, nodemask); > > + else > > + return __alloc_pages_nodemask(gfp_mask, order, > > preferred_nid, nodemask); > > - > > - if (new_page && PageTransHuge(page)) > > - prep_transhuge_page(new_page); > > > > return new_page; > > } > > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > > index 269b5df..e267488 100644 > > --- a/mm/huge_memory.c > > +++ b/mm/huge_memory.c > > @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(struct page *page) > > return (struct list_head *)&page[2].mapping; > > } > > > > -void prep_transhuge_page(struct page *page) > > +static void prep_transhuge_page(struct page *page) > > { > > /* > > * we use page->mapping and page->indexlru in second tail page > > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > > } > > > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > > + struct vm_area_struct *vma, unsigned long addr) > > +{ > > + struct page *page; > > + > > + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > > + vma, addr, numa_node_id(), true); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > > + int preferred_nid, nodemask_t *nmask) > > +{ > > + struct page *page; > > + > > + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > > + preferred_nid, nmask); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > > +{ > > + struct page *page; > > + > > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); > > + > > + page = alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, > > loff_t off, unsigned long flags, unsigned long size) > > { > > @@ -719,12 +758,11 @@ int do_huge_pmd_anonymous_page(struct vm_fault *vmf) > > return ret; > > } > > gfp = alloc_hugepage_direct_gfpmask(vma); > > - page = alloc_hugepage_vma(gfp, vma, haddr, HPAGE_PMD_ORDER); > > + page = alloc_transhuge_page_vma(gfp, vma, haddr); > > if (unlikely(!page)) { > > count_vm_event(THP_FAULT_FALLBACK); > > return VM_FAULT_FALLBACK; > > } > > - prep_transhuge_page(page); > > return __do_huge_pmd_anonymous_page(vmf, page, gfp); > > } > > > > @@ -1288,13 +1326,11 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) > > if (transparent_hugepage_enabled(vma) && > > !transparent_hugepage_debug_cow()) { > > huge_gfp = alloc_hugepage_direct_gfpmask(vma); > > - new_page = alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDER); > > + new_page = alloc_transhuge_page_vma(huge_gfp, vma, haddr); > > } else > > new_page = NULL; > > > > - if (likely(new_page)) { > > - prep_transhuge_page(new_page); > > - } else { > > + if (unlikely(!new_page)) { > > if (!page) { > > split_huge_pmd(vma, vmf->pmd, vmf->address); > > ret |= VM_FAULT_FALLBACK; > > diff --git a/mm/khugepaged.c b/mm/khugepaged.c > > index c01f177..d17a694 100644 > > --- a/mm/khugepaged.c > > +++ b/mm/khugepaged.c > > @@ -745,14 +745,13 @@ khugepaged_alloc_page(struct page **hpage, gfp_t gfp, int node) > > { > > VM_BUG_ON_PAGE(*hpage, *hpage); > > > > - *hpage = __alloc_pages_node(node, gfp, HPAGE_PMD_ORDER); > > + *hpage = alloc_transhuge_page_node(node, gfp); > > if (unlikely(!*hpage)) { > > count_vm_event(THP_COLLAPSE_ALLOC_FAILED); > > *hpage = ERR_PTR(-ENOMEM); > > return NULL; > > } > > > > - prep_transhuge_page(*hpage); > > count_vm_event(THP_COLLAPSE_ALLOC); > > return *hpage; > > } > > @@ -764,13 +763,7 @@ static int khugepaged_find_target_node(void) > > > > static inline struct page *alloc_khugepaged_hugepage(void) > > { > > - struct page *page; > > - > > - page = alloc_pages(alloc_hugepage_khugepaged_gfpmask(), > > - HPAGE_PMD_ORDER); > > - if (page) > > - prep_transhuge_page(page); > > - return page; > > + return alloc_transhuge_page(alloc_hugepage_khugepaged_gfpmask()); > > } > > > > static struct page *khugepaged_alloc_hugepage(bool *wait) > > diff --git a/mm/mempolicy.c b/mm/mempolicy.c > > index a2af6d5..aa24285 100644 > > --- a/mm/mempolicy.c > > +++ b/mm/mempolicy.c > > @@ -949,12 +949,10 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x > > else if (thp_migration_supported() && PageTransHuge(page)) { > > struct page *thp; > > > > - thp = alloc_pages_node(node, > > - (GFP_TRANSHUGE | __GFP_THISNODE), > > - HPAGE_PMD_ORDER); > > + thp = alloc_transhuge_page_node(node, > > + (GFP_TRANSHUGE | __GFP_THISNODE)); > > if (!thp) > > return NULL; > > - prep_transhuge_page(thp); > > return thp; > > } else > > return __alloc_pages_node(node, GFP_HIGHUSER_MOVABLE | > > @@ -1125,11 +1123,9 @@ static struct page *new_page(struct page *page, unsigned long start, int **x) > > } else if (thp_migration_supported() && PageTransHuge(page)) { > > struct page *thp; > > > > - thp = alloc_hugepage_vma(GFP_TRANSHUGE, vma, address, > > - HPAGE_PMD_ORDER); > > + thp = alloc_transhuge_page_vma(GFP_TRANSHUGE, vma, address); > > if (!thp) > > return NULL; > > - prep_transhuge_page(thp); > > return thp; > > } > > /* > > diff --git a/mm/migrate.c b/mm/migrate.c > > index e00814c..7f0486f 100644 > > --- a/mm/migrate.c > > +++ b/mm/migrate.c > > @@ -1472,12 +1472,10 @@ static struct page *new_page_node(struct page *p, unsigned long private, > > else if (thp_migration_supported() && PageTransHuge(p)) { > > struct page *thp; > > > > - thp = alloc_pages_node(pm->node, > > - (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM, > > - HPAGE_PMD_ORDER); > > + thp = alloc_transhuge_page_node(pm->node, > > + (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM); > > if (!thp) > > return NULL; > > - prep_transhuge_page(thp); > > return thp; > > } else > > return __alloc_pages_node(pm->node, > > @@ -2017,12 +2015,10 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, > > if (numamigrate_update_ratelimit(pgdat, HPAGE_PMD_NR)) > > goto out_dropref; > > > > - new_page = alloc_pages_node(node, > > - (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE), > > - HPAGE_PMD_ORDER); > > + new_page = alloc_transhuge_page_node(node, > > + (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE)); > > if (!new_page) > > goto out_fail; > > - prep_transhuge_page(new_page); > > > > isolated = numamigrate_isolate_page(pgdat, page); > > if (!isolated) { > > diff --git a/mm/shmem.c b/mm/shmem.c > > index 07a1d22..52468f7 100644 > > --- a/mm/shmem.c > > +++ b/mm/shmem.c > > @@ -1444,11 +1444,9 @@ static struct page *shmem_alloc_hugepage(gfp_t gfp, > > rcu_read_unlock(); > > > > shmem_pseudo_vma_init(&pvma, info, hindex); > > - page = alloc_pages_vma(gfp | __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN, > > - HPAGE_PMD_ORDER, &pvma, 0, numa_node_id(), true); > > + gfp |= __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN; > > + page = alloc_transhuge_page_vma(gfp, &pvma, 0); > > shmem_pseudo_vma_destroy(&pvma); > > - if (page) > > - prep_transhuge_page(page); > > return page; > > } > > > > -- > > 2.7.4 > > > > -- > > To unsubscribe, send a message with 'unsubscribe linux-mm' in > > the body to majordomo@kvack.org. For more info on Linux MM, > > see: http://www.linux-mm.org/ . > > Don't email: email@kvack.org > > -- > Michal Hocko > SUSE Labs -- Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f69.google.com (mail-wm0-f69.google.com [74.125.82.69]) by kanga.kvack.org (Postfix) with ESMTP id 079936B0038 for ; Tue, 17 Oct 2017 07:12:50 -0400 (EDT) Received: by mail-wm0-f69.google.com with SMTP id h191so723094wmd.15 for ; Tue, 17 Oct 2017 04:12:49 -0700 (PDT) Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id b17sor4422584edj.10.2017.10.17.04.12.48 for (Google Transport Security); Tue, 17 Oct 2017 04:12:48 -0700 (PDT) Date: Tue, 17 Oct 2017 14:12:46 +0300 From: "Kirill A. Shutemov" Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171017111246.7rhmy7klggxjozom@node.shutemov.name> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> Sender: owner-linux-mm@kvack.org List-ID: To: changbin.du@intel.com Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org On Mon, Oct 16, 2017 at 05:19:16PM +0800, changbin.du@intel.com wrote: > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > } > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr) > +{ > + struct page *page; > + > + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + vma, addr, numa_node_id(), true); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask) > +{ > + struct page *page; > + > + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + preferred_nid, nmask); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > +{ > + struct page *page; > + > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); Why do you check for __GFP_COMP only in this helper? > + page = alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); And still apply __GFP_COMP anyway? > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, > loff_t off, unsigned long flags, unsigned long size) > { -- Kirill A. Shutemov -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f69.google.com (mail-wm0-f69.google.com [74.125.82.69]) by kanga.kvack.org (Postfix) with ESMTP id 2E02A6B0069 for ; Tue, 17 Oct 2017 07:22:17 -0400 (EDT) Received: by mail-wm0-f69.google.com with SMTP id v127so749153wma.3 for ; Tue, 17 Oct 2017 04:22:17 -0700 (PDT) Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id v23sor4403202eda.27.2017.10.17.04.22.15 for (Google Transport Security); Tue, 17 Oct 2017 04:22:16 -0700 (PDT) Date: Tue, 17 Oct 2017 14:22:14 +0300 From: "Kirill A. Shutemov" Subject: Re: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Message-ID: <20171017112214.n5emzjzstmbktn6m@node.shutemov.name> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-3-git-send-email-changbin.du@intel.com> <20171017102203.u2v3p2ivuogu4rk6@dhcp22.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171017102203.u2v3p2ivuogu4rk6@dhcp22.suse.cz> Sender: owner-linux-mm@kvack.org List-ID: To: Michal Hocko Cc: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org On Tue, Oct 17, 2017 at 12:22:03PM +0200, Michal Hocko wrote: > On Mon 16-10-17 17:19:17, changbin.du@intel.com wrote: > > From: Changbin Du > > > > The current name free_{huge,transhuge}_page are paired with > > alloc_{huge,transhuge}_page functions, but the actual page free > > function is still free_page() which will indirectly call > > free_{huge,transhuge}_page. So this patch removes this confusion > > by renaming all the compound page dtors. > > Is this code churn really worth it? Getting naming straight is kinda nit. :) But I don't feel strong either way. -- Kirill A. Shutemov -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f197.google.com (mail-wr0-f197.google.com [209.85.128.197]) by kanga.kvack.org (Postfix) with ESMTP id 8C7AB6B0038 for ; Tue, 17 Oct 2017 08:00:25 -0400 (EDT) Received: by mail-wr0-f197.google.com with SMTP id y39so704233wrd.17 for ; Tue, 17 Oct 2017 05:00:25 -0700 (PDT) Received: from mx2.suse.de (mx2.suse.de. [195.135.220.15]) by mx.google.com with ESMTPS id g206si6964833wmg.269.2017.10.17.05.00.23 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 17 Oct 2017 05:00:23 -0700 (PDT) Date: Tue, 17 Oct 2017 14:00:22 +0200 From: Michal Hocko Subject: Re: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Message-ID: <20171017120022.m4gblhcfs7xf7zld@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-3-git-send-email-changbin.du@intel.com> <20171017102203.u2v3p2ivuogu4rk6@dhcp22.suse.cz> <20171017112214.n5emzjzstmbktn6m@node.shutemov.name> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171017112214.n5emzjzstmbktn6m@node.shutemov.name> Sender: owner-linux-mm@kvack.org List-ID: To: "Kirill A. Shutemov" Cc: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org On Tue 17-10-17 14:22:14, Kirill A. Shutemov wrote: > On Tue, Oct 17, 2017 at 12:22:03PM +0200, Michal Hocko wrote: > > On Mon 16-10-17 17:19:17, changbin.du@intel.com wrote: > > > From: Changbin Du > > > > > > The current name free_{huge,transhuge}_page are paired with > > > alloc_{huge,transhuge}_page functions, but the actual page free > > > function is still free_page() which will indirectly call > > > free_{huge,transhuge}_page. So this patch removes this confusion > > > by renaming all the compound page dtors. > > > > Is this code churn really worth it? > > Getting naming straight is kinda nit. :) yes > But I don't feel strong either way. Me neither, I am just trying to understand why the patch has been created? Is it a preparation for some other changes? If it was removing some code it would be much more clear but it actually adds twice as much as it removes so it doesn't save anything there. It makes the API more explicit which might be good but is it worth that? -- Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oi0-f71.google.com (mail-oi0-f71.google.com [209.85.218.71]) by kanga.kvack.org (Postfix) with ESMTP id C8ACC6B0038 for ; Tue, 17 Oct 2017 19:28:20 -0400 (EDT) Received: by mail-oi0-f71.google.com with SMTP id c202so3036947oih.8 for ; Tue, 17 Oct 2017 16:28:20 -0700 (PDT) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org. [140.211.169.12]) by mx.google.com with ESMTPS id u83si1418413wmu.6.2017.10.17.16.28.19 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Oct 2017 16:28:19 -0700 (PDT) Date: Tue, 17 Oct 2017 16:28:16 -0700 From: Andrew Morton Subject: Re: [PATCH 0/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-Id: <20171017162816.c5751bda5d51d3bf560b8503@linux-foundation.org> In-Reply-To: <1508145557-9944-1-git-send-email-changbin.du@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-linux-mm@kvack.org List-ID: To: changbin.du@intel.com Cc: corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org On Mon, 16 Oct 2017 17:19:15 +0800 changbin.du@intel.com wrote: > The first one introduce new interfaces, the second one kills naming confusion. > The aim is to remove duplicated code and simplify transparent huge page > allocation. These introduce various allnoconfig build errors. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-f200.google.com (mail-pf0-f200.google.com [209.85.192.200]) by kanga.kvack.org (Postfix) with ESMTP id 869FD6B0033 for ; Wed, 18 Oct 2017 07:07:19 -0400 (EDT) Received: by mail-pf0-f200.google.com with SMTP id p2so3314726pfk.13 for ; Wed, 18 Oct 2017 04:07:19 -0700 (PDT) Received: from mga04.intel.com (mga04.intel.com. [192.55.52.120]) by mx.google.com with ESMTPS id a91si656223pla.788.2017.10.18.04.07.18 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 18 Oct 2017 04:07:18 -0700 (PDT) Date: Wed, 18 Oct 2017 19:00:26 +0800 From: "Du, Changbin" Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171018110026.GA4352@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="W/nzBZO5zC0uMSeA" Content-Disposition: inline In-Reply-To: <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> Sender: owner-linux-mm@kvack.org List-ID: To: Michal Hocko Cc: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org --W/nzBZO5zC0uMSeA Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi Hocko, On Tue, Oct 17, 2017 at 12:20:52PM +0200, Michal Hocko wrote: > [CC Kirill] >=20 > On Mon 16-10-17 17:19:16, changbin.du@intel.com wrote: > > From: Changbin Du > >=20 > > This patch introduced 4 new interfaces to allocate a prepared > > transparent huge page. > > - alloc_transhuge_page_vma > > - alloc_transhuge_page_nodemask > > - alloc_transhuge_page_node > > - alloc_transhuge_page > >=20 > > The aim is to remove duplicated code and simplify transparent > > huge page allocation. These are similar to alloc_hugepage_xxx > > which are for hugetlbfs pages. This patch does below changes: > > - define alloc_transhuge_page_xxx interfaces > > - apply them to all existing code > > - declare prep_transhuge_page as static since no others use it > > - remove alloc_hugepage_vma definition since it no longer has users >=20 > So what exactly is the advantage of the new API? The diffstat doesn't > sound very convincing to me. > The caller only need one step to allocate thp. Several LOCs removed for all= the caller side with this change. So it's little more convinent. > > Signed-off-by: Changbin Du > > --- > > include/linux/gfp.h | 4 ---- > > include/linux/huge_mm.h | 13 ++++++++++++- > > include/linux/migrate.h | 14 +++++--------- > > mm/huge_memory.c | 50 +++++++++++++++++++++++++++++++++++++++++= +------- > > mm/khugepaged.c | 11 ++--------- > > mm/mempolicy.c | 10 +++------- > > mm/migrate.c | 12 ++++-------- > > mm/shmem.c | 6 ++---- > > 8 files changed, 71 insertions(+), 49 deletions(-) > >=20 > > diff --git a/include/linux/gfp.h b/include/linux/gfp.h > > index f780718..855c72e 100644 > > --- a/include/linux/gfp.h > > +++ b/include/linux/gfp.h > > @@ -507,15 +507,11 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) > > extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, > > struct vm_area_struct *vma, unsigned long addr, > > int node, bool hugepage); > > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > > - alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) > > #else > > #define alloc_pages(gfp_mask, order) \ > > alloc_pages_node(numa_node_id(), gfp_mask, order) > > #define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ > > alloc_pages(gfp_mask, order) > > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > > - alloc_pages(gfp_mask, order) > > #endif > > #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) > > #define alloc_page_vma(gfp_mask, vma, addr) \ > > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > > index 14bc21c..1dd2c33 100644 > > --- a/include/linux/huge_mm.h > > +++ b/include/linux/huge_mm.h > > @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct = file *filp, > > unsigned long addr, unsigned long len, unsigned long pgoff, > > unsigned long flags); > > =20 > > -extern void prep_transhuge_page(struct page *page); > > extern void free_transhuge_page(struct page *page); > > =20 > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > > + struct vm_area_struct *vma, unsigned long addr); > > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > > + int preferred_nid, nodemask_t *nmask); > > + > > +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gf= p_mask) > > +{ > > + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); > > +} > > + > > +struct page *alloc_transhuge_page(gfp_t gfp_mask); > > + > > bool can_split_huge_page(struct page *page, int *pextra_pins); > > int split_huge_page_to_list(struct page *page, struct list_head *list); > > static inline int split_huge_page(struct page *page) > > diff --git a/include/linux/migrate.h b/include/linux/migrate.h > > index 643c7ae..70a00f3 100644 > > --- a/include/linux/migrate.h > > +++ b/include/linux/migrate.h > > @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct= page *page, > > return alloc_huge_page_nodemask(page_hstate(compound_head(page)), > > preferred_nid, nodemask); > > =20 > > - if (thp_migration_supported() && PageTransHuge(page)) { > > - order =3D HPAGE_PMD_ORDER; > > - gfp_mask |=3D GFP_TRANSHUGE; > > - } > > - > > if (PageHighMem(page) || (zone_idx(page_zone(page)) =3D=3D ZONE_MOVAB= LE)) > > gfp_mask |=3D __GFP_HIGHMEM; > > =20 > > - new_page =3D __alloc_pages_nodemask(gfp_mask, order, > > + if (thp_migration_supported() && PageTransHuge(page)) > > + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, > > + preferred_nid, nodemask); > > + else > > + return __alloc_pages_nodemask(gfp_mask, order, > > preferred_nid, nodemask); > > - > > - if (new_page && PageTransHuge(page)) > > - prep_transhuge_page(new_page); > > =20 > > return new_page; > > } > > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > > index 269b5df..e267488 100644 > > --- a/mm/huge_memory.c > > +++ b/mm/huge_memory.c > > @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(= struct page *page) > > return (struct list_head *)&page[2].mapping; > > } > > =20 > > -void prep_transhuge_page(struct page *page) > > +static void prep_transhuge_page(struct page *page) > > { > > /* > > * we use page->mapping and page->indexlru in second tail page > > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > > } > > =20 > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > > + struct vm_area_struct *vma, unsigned long addr) > > +{ > > + struct page *page; > > + > > + page =3D alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > > + vma, addr, numa_node_id(), true); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > > + int preferred_nid, nodemask_t *nmask) > > +{ > > + struct page *page; > > + > > + page =3D __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDE= R, > > + preferred_nid, nmask); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > > +{ > > + struct page *page; > > + > > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); > > + > > + page =3D alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long= len, > > loff_t off, unsigned long flags, unsigned long size) > > { > > @@ -719,12 +758,11 @@ int do_huge_pmd_anonymous_page(struct vm_fault *v= mf) > > return ret; > > } > > gfp =3D alloc_hugepage_direct_gfpmask(vma); > > - page =3D alloc_hugepage_vma(gfp, vma, haddr, HPAGE_PMD_ORDER); > > + page =3D alloc_transhuge_page_vma(gfp, vma, haddr); > > if (unlikely(!page)) { > > count_vm_event(THP_FAULT_FALLBACK); > > return VM_FAULT_FALLBACK; > > } > > - prep_transhuge_page(page); > > return __do_huge_pmd_anonymous_page(vmf, page, gfp); > > } > > =20 > > @@ -1288,13 +1326,11 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, p= md_t orig_pmd) > > if (transparent_hugepage_enabled(vma) && > > !transparent_hugepage_debug_cow()) { > > huge_gfp =3D alloc_hugepage_direct_gfpmask(vma); > > - new_page =3D alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDE= R); > > + new_page =3D alloc_transhuge_page_vma(huge_gfp, vma, haddr); > > } else > > new_page =3D NULL; > > =20 > > - if (likely(new_page)) { > > - prep_transhuge_page(new_page); > > - } else { > > + if (unlikely(!new_page)) { > > if (!page) { > > split_huge_pmd(vma, vmf->pmd, vmf->address); > > ret |=3D VM_FAULT_FALLBACK; > > diff --git a/mm/khugepaged.c b/mm/khugepaged.c > > index c01f177..d17a694 100644 > > --- a/mm/khugepaged.c > > +++ b/mm/khugepaged.c > > @@ -745,14 +745,13 @@ khugepaged_alloc_page(struct page **hpage, gfp_t = gfp, int node) > > { > > VM_BUG_ON_PAGE(*hpage, *hpage); > > =20 > > - *hpage =3D __alloc_pages_node(node, gfp, HPAGE_PMD_ORDER); > > + *hpage =3D alloc_transhuge_page_node(node, gfp); > > if (unlikely(!*hpage)) { > > count_vm_event(THP_COLLAPSE_ALLOC_FAILED); > > *hpage =3D ERR_PTR(-ENOMEM); > > return NULL; > > } > > =20 > > - prep_transhuge_page(*hpage); > > count_vm_event(THP_COLLAPSE_ALLOC); > > return *hpage; > > } > > @@ -764,13 +763,7 @@ static int khugepaged_find_target_node(void) > > =20 > > static inline struct page *alloc_khugepaged_hugepage(void) > > { > > - struct page *page; > > - > > - page =3D alloc_pages(alloc_hugepage_khugepaged_gfpmask(), > > - HPAGE_PMD_ORDER); > > - if (page) > > - prep_transhuge_page(page); > > - return page; > > + return alloc_transhuge_page(alloc_hugepage_khugepaged_gfpmask()); > > } > > =20 > > static struct page *khugepaged_alloc_hugepage(bool *wait) > > diff --git a/mm/mempolicy.c b/mm/mempolicy.c > > index a2af6d5..aa24285 100644 > > --- a/mm/mempolicy.c > > +++ b/mm/mempolicy.c > > @@ -949,12 +949,10 @@ static struct page *new_node_page(struct page *pa= ge, unsigned long node, int **x > > else if (thp_migration_supported() && PageTransHuge(page)) { > > struct page *thp; > > =20 > > - thp =3D alloc_pages_node(node, > > - (GFP_TRANSHUGE | __GFP_THISNODE), > > - HPAGE_PMD_ORDER); > > + thp =3D alloc_transhuge_page_node(node, > > + (GFP_TRANSHUGE | __GFP_THISNODE)); > > if (!thp) > > return NULL; > > - prep_transhuge_page(thp); > > return thp; > > } else > > return __alloc_pages_node(node, GFP_HIGHUSER_MOVABLE | > > @@ -1125,11 +1123,9 @@ static struct page *new_page(struct page *page, = unsigned long start, int **x) > > } else if (thp_migration_supported() && PageTransHuge(page)) { > > struct page *thp; > > =20 > > - thp =3D alloc_hugepage_vma(GFP_TRANSHUGE, vma, address, > > - HPAGE_PMD_ORDER); > > + thp =3D alloc_transhuge_page_vma(GFP_TRANSHUGE, vma, address); > > if (!thp) > > return NULL; > > - prep_transhuge_page(thp); > > return thp; > > } > > /* > > diff --git a/mm/migrate.c b/mm/migrate.c > > index e00814c..7f0486f 100644 > > --- a/mm/migrate.c > > +++ b/mm/migrate.c > > @@ -1472,12 +1472,10 @@ static struct page *new_page_node(struct page *= p, unsigned long private, > > else if (thp_migration_supported() && PageTransHuge(p)) { > > struct page *thp; > > =20 > > - thp =3D alloc_pages_node(pm->node, > > - (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM, > > - HPAGE_PMD_ORDER); > > + thp =3D alloc_transhuge_page_node(pm->node, > > + (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM); > > if (!thp) > > return NULL; > > - prep_transhuge_page(thp); > > return thp; > > } else > > return __alloc_pages_node(pm->node, > > @@ -2017,12 +2015,10 @@ int migrate_misplaced_transhuge_page(struct mm_= struct *mm, > > if (numamigrate_update_ratelimit(pgdat, HPAGE_PMD_NR)) > > goto out_dropref; > > =20 > > - new_page =3D alloc_pages_node(node, > > - (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE), > > - HPAGE_PMD_ORDER); > > + new_page =3D alloc_transhuge_page_node(node, > > + (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE)); > > if (!new_page) > > goto out_fail; > > - prep_transhuge_page(new_page); > > =20 > > isolated =3D numamigrate_isolate_page(pgdat, page); > > if (!isolated) { > > diff --git a/mm/shmem.c b/mm/shmem.c > > index 07a1d22..52468f7 100644 > > --- a/mm/shmem.c > > +++ b/mm/shmem.c > > @@ -1444,11 +1444,9 @@ static struct page *shmem_alloc_hugepage(gfp_t g= fp, > > rcu_read_unlock(); > > =20 > > shmem_pseudo_vma_init(&pvma, info, hindex); > > - page =3D alloc_pages_vma(gfp | __GFP_COMP | __GFP_NORETRY | __GFP_NOW= ARN, > > - HPAGE_PMD_ORDER, &pvma, 0, numa_node_id(), true); > > + gfp |=3D __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN; > > + page =3D alloc_transhuge_page_vma(gfp, &pvma, 0); > > shmem_pseudo_vma_destroy(&pvma); > > - if (page) > > - prep_transhuge_page(page); > > return page; > > } > > =20 > > --=20 > > 2.7.4 > >=20 > > -- > > To unsubscribe, send a message with 'unsubscribe linux-mm' in > > the body to majordomo@kvack.org. For more info on Linux MM, > > see: http://www.linux-mm.org/ . > > Don't email: email@kvack.org >=20 > --=20 > Michal Hocko > SUSE Labs --=20 Thanks, Changbin Du --W/nzBZO5zC0uMSeA Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJZ5zRKAAoJEAanuZwLnPNUT/cIAJKvD87yGe3HbMgNYvNO5xmV SNw2SDJqvxcNLc3+UUb7aL+Tclt4r20qbwnVQp9vA03es5Zv4bAHfeN7y2g5/uxU AbHU/nAFfZ8ma3kMdy29YQCwW7IVAMgNUcIHiLwE/pdf5hgSPQxVO1BOar1nhGjq 0866XRuzdMhu18SyoHtJrT5rFyUXKyAf9kW/GirRlSK437v57JVE+oI9lf7Hu/U7 GYjcTz8e2F7FFIFlbwgd5J3qK9m07L/7KqIcglohNSGAyU6BiyRlz+Ep4SbvWIhw ZLk3u7tIH1GgceKIYkLOzXPktIkFqijt1FJjcx77Eivov/ITRqj5cMcKR5S0rig= =bysx -----END PGP SIGNATURE----- --W/nzBZO5zC0uMSeA-- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f71.google.com (mail-pg0-f71.google.com [74.125.83.71]) by kanga.kvack.org (Postfix) with ESMTP id E312D6B0038 for ; Wed, 18 Oct 2017 07:08:18 -0400 (EDT) Received: by mail-pg0-f71.google.com with SMTP id b192so3880050pga.14 for ; Wed, 18 Oct 2017 04:08:18 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com. [134.134.136.100]) by mx.google.com with ESMTPS id p33si7648471pld.51.2017.10.18.04.08.17 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 18 Oct 2017 04:08:18 -0700 (PDT) Date: Wed, 18 Oct 2017 19:01:15 +0800 From: "Du, Changbin" Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171018110114.GB4352@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> <20171017111246.7rhmy7klggxjozom@node.shutemov.name> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="MfFXiAuoTsnnDAfZ" Content-Disposition: inline In-Reply-To: <20171017111246.7rhmy7klggxjozom@node.shutemov.name> Sender: owner-linux-mm@kvack.org List-ID: To: "Kirill A. Shutemov" Cc: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org --MfFXiAuoTsnnDAfZ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, Oct 17, 2017 at 02:12:46PM +0300, Kirill A. Shutemov wrote: > On Mon, Oct 16, 2017 at 05:19:16PM +0800, changbin.du@intel.com wrote: > > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > > } > > =20 > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > > + struct vm_area_struct *vma, unsigned long addr) > > +{ > > + struct page *page; > > + > > + page =3D alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > > + vma, addr, numa_node_id(), true); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > > + int preferred_nid, nodemask_t *nmask) > > +{ > > + struct page *page; > > + > > + page =3D __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDE= R, > > + preferred_nid, nmask); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > > +{ > > + struct page *page; > > + > > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); >=20 > Why do you check for __GFP_COMP only in this helper? >=20 > > + page =3D alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); >=20 > And still apply __GFP_COMP anyway? > This is a mistake, will removed. Thanks. > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long= len, > > loff_t off, unsigned long flags, unsigned long size) > > { >=20 > --=20 > Kirill A. Shutemov --=20 Thanks, Changbin Du --MfFXiAuoTsnnDAfZ Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJZ5zR6AAoJEAanuZwLnPNUYDoH/jZC79Ky3xbVzdKV7OuGEi7f SPCfRfcFX/erKjb1ugIJA8DajO+nDntnE50Rt9F9wciuR8bcnZv+GWvWJ0WZbra0 p6qQbJsCcQiOEhS4mgUCMIhR6FjL+udUk6R3IIQ2Pgkg5/eig+vfwUqtc3KOJQc2 FfClenU5iqwer98gV0q0i1iGM7gPmsQ7ggK6NpXvPfm/dHfHZhekjYiGePaNYjLN 8MPsHGhXW5mETpxbriDuQMY9ZP6WLdtOVPHTKRPBr/pRnSMfGwmHsfVFyGfuYj6l mK5cZPBQnw+DI+uF4fVvv6TMRitFPdcO//MLwV5M+EV/utcXVCz6vms5yCquYg0= =mWo8 -----END PGP SIGNATURE----- --MfFXiAuoTsnnDAfZ-- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-f197.google.com (mail-pf0-f197.google.com [209.85.192.197]) by kanga.kvack.org (Postfix) with ESMTP id 811506B0033 for ; Wed, 18 Oct 2017 07:09:00 -0400 (EDT) Received: by mail-pf0-f197.google.com with SMTP id a8so3327458pfc.6 for ; Wed, 18 Oct 2017 04:09:00 -0700 (PDT) Received: from mga05.intel.com (mga05.intel.com. [192.55.52.43]) by mx.google.com with ESMTPS id b4si979949plb.202.2017.10.18.04.08.59 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 18 Oct 2017 04:08:59 -0700 (PDT) Date: Wed, 18 Oct 2017 19:02:08 +0800 From: "Du, Changbin" Subject: Re: [PATCH 0/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171018110208.GC4352@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <20171017162816.c5751bda5d51d3bf560b8503@linux-foundation.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="kfjH4zxOES6UT95V" Content-Disposition: inline In-Reply-To: <20171017162816.c5751bda5d51d3bf560b8503@linux-foundation.org> Sender: owner-linux-mm@kvack.org List-ID: To: Andrew Morton Cc: changbin.du@intel.com, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org --kfjH4zxOES6UT95V Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi Morton, On Tue, Oct 17, 2017 at 04:28:16PM -0700, Andrew Morton wrote: > On Mon, 16 Oct 2017 17:19:15 +0800 changbin.du@intel.com wrote: >=20 > > The first one introduce new interfaces, the second one kills naming con= fusion. > > The aim is to remove duplicated code and simplify transparent huge page > > allocation. >=20 > These introduce various allnoconfig build errors. Thanks, I will fix and have more test. --=20 Thanks, Changbin Du --kfjH4zxOES6UT95V Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJZ5zSwAAoJEAanuZwLnPNUmI4H/ja8BV3PjCpkZMHQJkoJp6i+ Hu9KbqxodBGSaAfwjg/gYxi15SGx8xSwA5x4AHdI7HdW8CK5FuTkQErbSWz8iTQy /DFq3/uWu6vg8MYEEWZJDhDg7DjVLaP2MHA1A01dtqN3Djn0pOVrdT52fhayVA+K Nus1XRIBK+AwFRN1tck1SBc/ubowQadvOrsg7Dpkv5yITgLx/VpXioAObYpTp8HO VWHTT9kXiKHSgdFkTVnClXFCieJHX86dqV+gcIn54980klH2R0JkCbp0XKWB0yVf PbqCbU61XZf/1h8HSXxQAuv6p6QdAtxHuSL9C2bkhzII6v6FeuA31c7R9xtklU8= =alrn -----END PGP SIGNATURE----- --kfjH4zxOES6UT95V-- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f69.google.com (mail-pg0-f69.google.com [74.125.83.69]) by kanga.kvack.org (Postfix) with ESMTP id 4CD7C6B0253 for ; Wed, 18 Oct 2017 11:55:27 -0400 (EDT) Received: by mail-pg0-f69.google.com with SMTP id g6so4367754pgn.11 for ; Wed, 18 Oct 2017 08:55:27 -0700 (PDT) Received: from mga05.intel.com (mga05.intel.com. [192.55.52.43]) by mx.google.com with ESMTPS id 69si3113488plc.528.2017.10.18.08.55.25 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 18 Oct 2017 08:55:26 -0700 (PDT) Date: Wed, 18 Oct 2017 23:54:55 +0800 From: kbuild test robot Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <201710182319.H5PtDUyn%fengguang.wu@intel.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="/04w6evG8XlLl3ft" Content-Disposition: inline In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> Sender: owner-linux-mm@kvack.org List-ID: To: changbin.du@intel.com Cc: kbuild-all@01.org, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org --/04w6evG8XlLl3ft Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Changbin, [auto build test ERROR on mmotm/master] [also build test ERROR on v4.14-rc5 next-20171017] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/changbin-du-intel-com/mm-thp-introduce-dedicated-transparent-huge-page-allocation-interfaces/20171018-230128 base: git://git.cmpxchg.org/linux-mmotm.git master config: i386-randconfig-x003-201742 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from mm/shmem.c:70:0: include/linux/migrate.h: In function 'new_page_nodemask': include/linux/migrate.h:49:10: error: implicit declaration of function 'alloc_transhuge_page_nodemask' [-Werror=implicit-function-declaration] return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/migrate.h:49:10: warning: return makes pointer from integer without a cast [-Wint-conversion] return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ preferred_nid, nodemask); ~~~~~~~~~~~~~~~~~~~~~~~~ mm/shmem.c: In function 'shmem_alloc_hugepage': >> mm/shmem.c:1448:9: error: implicit declaration of function 'alloc_transhuge_page_vma' [-Werror=implicit-function-declaration] page = alloc_transhuge_page_vma(gfp, &pvma, 0); ^~~~~~~~~~~~~~~~~~~~~~~~ >> mm/shmem.c:1448:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion] page = alloc_transhuge_page_vma(gfp, &pvma, 0); ^ cc1: some warnings being treated as errors vim +/alloc_transhuge_page_vma +1448 mm/shmem.c 1423 1424 static struct page *shmem_alloc_hugepage(gfp_t gfp, 1425 struct shmem_inode_info *info, pgoff_t index) 1426 { 1427 struct vm_area_struct pvma; 1428 struct inode *inode = &info->vfs_inode; 1429 struct address_space *mapping = inode->i_mapping; 1430 pgoff_t idx, hindex; 1431 void __rcu **results; 1432 struct page *page; 1433 1434 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE)) 1435 return NULL; 1436 1437 hindex = round_down(index, HPAGE_PMD_NR); 1438 rcu_read_lock(); 1439 if (radix_tree_gang_lookup_slot(&mapping->page_tree, &results, &idx, 1440 hindex, 1) && idx < hindex + HPAGE_PMD_NR) { 1441 rcu_read_unlock(); 1442 return NULL; 1443 } 1444 rcu_read_unlock(); 1445 1446 shmem_pseudo_vma_init(&pvma, info, hindex); 1447 gfp |= __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN; > 1448 page = alloc_transhuge_page_vma(gfp, &pvma, 0); 1449 shmem_pseudo_vma_destroy(&pvma); 1450 return page; 1451 } 1452 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --/04w6evG8XlLl3ft Content-Type: application/gzip Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 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 o/w/3JFHtWjCAQA= --/04w6evG8XlLl3ft-- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f72.google.com (mail-pg0-f72.google.com [74.125.83.72]) by kanga.kvack.org (Postfix) with ESMTP id 3A5506B0253 for ; Wed, 18 Oct 2017 12:02:30 -0400 (EDT) Received: by mail-pg0-f72.google.com with SMTP id 191so4408648pgd.0 for ; Wed, 18 Oct 2017 09:02:30 -0700 (PDT) Received: from mga06.intel.com (mga06.intel.com. [134.134.136.31]) by mx.google.com with ESMTPS id t28si7677077pfg.6.2017.10.18.09.02.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 18 Oct 2017 09:02:28 -0700 (PDT) Date: Thu, 19 Oct 2017 00:01:45 +0800 From: kbuild test robot Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <201710182351.IgCZ78nr%fengguang.wu@intel.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="IJpNTDwzlM2Ie8A6" Content-Disposition: inline In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> Sender: owner-linux-mm@kvack.org List-ID: To: changbin.du@intel.com Cc: kbuild-all@01.org, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org --IJpNTDwzlM2Ie8A6 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Changbin, [auto build test ERROR on mmotm/master] [also build test ERROR on v4.14-rc5 next-20171017] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/changbin-du-intel-com/mm-thp-introduce-dedicated-transparent-huge-page-allocation-interfaces/20171018-230128 base: git://git.cmpxchg.org/linux-mmotm.git master config: i386-randconfig-x001-201742 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from include/linux/balloon_compaction.h:48:0, from drivers/virtio/virtio_balloon.c:29: include/linux/migrate.h: In function 'new_page_nodemask': >> include/linux/migrate.h:49:10: error: implicit declaration of function 'alloc_transhuge_page_nodemask' [-Werror=implicit-function-declaration] return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> include/linux/migrate.h:49:10: warning: return makes pointer from integer without a cast [-Wint-conversion] return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ preferred_nid, nodemask); ~~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +/alloc_transhuge_page_nodemask +49 include/linux/migrate.h 33 34 static inline struct page *new_page_nodemask(struct page *page, 35 int preferred_nid, nodemask_t *nodemask) 36 { 37 gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL; 38 unsigned int order = 0; 39 struct page *new_page = NULL; 40 41 if (PageHuge(page)) 42 return alloc_huge_page_nodemask(page_hstate(compound_head(page)), 43 preferred_nid, nodemask); 44 45 if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) 46 gfp_mask |= __GFP_HIGHMEM; 47 48 if (thp_migration_supported() && PageTransHuge(page)) > 49 return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, 50 preferred_nid, nodemask); 51 else 52 return __alloc_pages_nodemask(gfp_mask, order, 53 preferred_nid, nodemask); 54 55 return new_page; 56 } 57 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --IJpNTDwzlM2Ie8A6 Content-Type: application/gzip Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 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 --IJpNTDwzlM2Ie8A6-- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f72.google.com (mail-pg0-f72.google.com [74.125.83.72]) by kanga.kvack.org (Postfix) with ESMTP id 3E24A6B0033 for ; Thu, 19 Oct 2017 08:49:35 -0400 (EDT) Received: by mail-pg0-f72.google.com with SMTP id l24so6797713pgu.22 for ; Thu, 19 Oct 2017 05:49:35 -0700 (PDT) Received: from mx2.suse.de (mx2.suse.de. [195.135.220.15]) by mx.google.com with ESMTPS id a8si8647720pgu.368.2017.10.19.05.49.34 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 19 Oct 2017 05:49:34 -0700 (PDT) Date: Thu, 19 Oct 2017 14:49:31 +0200 From: Michal Hocko Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171019124931.p5zdvs2kdwu73mwh@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> <20171018110026.GA4352@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171018110026.GA4352@intel.com> Sender: owner-linux-mm@kvack.org List-ID: To: "Du, Changbin" Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org On Wed 18-10-17 19:00:26, Du, Changbin wrote: > Hi Hocko, > > On Tue, Oct 17, 2017 at 12:20:52PM +0200, Michal Hocko wrote: > > [CC Kirill] > > > > On Mon 16-10-17 17:19:16, changbin.du@intel.com wrote: > > > From: Changbin Du > > > > > > This patch introduced 4 new interfaces to allocate a prepared > > > transparent huge page. > > > - alloc_transhuge_page_vma > > > - alloc_transhuge_page_nodemask > > > - alloc_transhuge_page_node > > > - alloc_transhuge_page > > > > > > The aim is to remove duplicated code and simplify transparent > > > huge page allocation. These are similar to alloc_hugepage_xxx > > > which are for hugetlbfs pages. This patch does below changes: > > > - define alloc_transhuge_page_xxx interfaces > > > - apply them to all existing code > > > - declare prep_transhuge_page as static since no others use it > > > - remove alloc_hugepage_vma definition since it no longer has users > > > > So what exactly is the advantage of the new API? The diffstat doesn't > > sound very convincing to me. > > > The caller only need one step to allocate thp. Several LOCs removed for all the > caller side with this change. So it's little more convinent. Yeah, but the overall result is more code. So I am not really convinced. -- Michal Hocko SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-f199.google.com (mail-pf0-f199.google.com [209.85.192.199]) by kanga.kvack.org (Postfix) with ESMTP id 17CD36B0038 for ; Fri, 20 Oct 2017 04:38:38 -0400 (EDT) Received: by mail-pf0-f199.google.com with SMTP id n89so9281733pfk.17 for ; Fri, 20 Oct 2017 01:38:38 -0700 (PDT) Received: from mga04.intel.com (mga04.intel.com. [192.55.52.120]) by mx.google.com with ESMTPS id u9si366915plz.76.2017.10.20.01.38.37 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Oct 2017 01:38:37 -0700 (PDT) Date: Fri, 20 Oct 2017 16:31:42 +0800 From: "Du, Changbin" Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171020083142.GA18017@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> <20171018110026.GA4352@intel.com> <20171019124931.p5zdvs2kdwu73mwh@dhcp22.suse.cz> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="LQksG6bCIzRHxTLp" Content-Disposition: inline In-Reply-To: <20171019124931.p5zdvs2kdwu73mwh@dhcp22.suse.cz> Sender: owner-linux-mm@kvack.org List-ID: To: Michal Hocko Cc: "Du, Changbin" , akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org --LQksG6bCIzRHxTLp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi Hocko, On Thu, Oct 19, 2017 at 02:49:31PM +0200, Michal Hocko wrote: > On Wed 18-10-17 19:00:26, Du, Changbin wrote: > > Hi Hocko, > >=20 > > On Tue, Oct 17, 2017 at 12:20:52PM +0200, Michal Hocko wrote: > > > [CC Kirill] > > >=20 > > > On Mon 16-10-17 17:19:16, changbin.du@intel.com wrote: > > > > From: Changbin Du > > > >=20 > > > > This patch introduced 4 new interfaces to allocate a prepared > > > > transparent huge page. > > > > - alloc_transhuge_page_vma > > > > - alloc_transhuge_page_nodemask > > > > - alloc_transhuge_page_node > > > > - alloc_transhuge_page > > > >=20 > > > > The aim is to remove duplicated code and simplify transparent > > > > huge page allocation. These are similar to alloc_hugepage_xxx > > > > which are for hugetlbfs pages. This patch does below changes: > > > > - define alloc_transhuge_page_xxx interfaces > > > > - apply them to all existing code > > > > - declare prep_transhuge_page as static since no others use it > > > > - remove alloc_hugepage_vma definition since it no longer has use= rs > > >=20 > > > So what exactly is the advantage of the new API? The diffstat doesn't > > > sound very convincing to me. > > > > > The caller only need one step to allocate thp. Several LOCs removed for= all the > > caller side with this change. So it's little more convinent. >=20 > Yeah, but the overall result is more code. So I am not really convinced.= =20 Yes, but some of code are just to make compiler happy (declarations). These= are just simple light wrappers same as other functions in kernel. At least the = code readbility is improved by this, two steps allocation merged into one so duplicated logic removed. > --=20 > Michal Hocko > SUSE Labs --=20 Thanks, Changbin Du --LQksG6bCIzRHxTLp Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJZ6bRuAAoJEAanuZwLnPNUuToH/1uns9QTLOZpMD5Bvubzc34e 72GQi2wUDwqXSWfFD5AP99SPayuh36o8vXRgCdb0ZCl+HMBcuU1aMZ6JqMu8Q781 4J8bKPUVpLykZbM3iRNRp993y7vWtHaWY0m5rEO5fofA/V5vKpWWCNqNgoQSvM/O d1v/4VMoQ9v8Y6G2BjYzWwdlv9XpSLyGPrnRp8Ohw21lGRIq8MPdilWOZlnSd7QM VCGPinGe0qCnCFaQtI+ZB9blxq4Ilbgq/ZAiX1WUMPNAmTdi7OF5GKxJoLquoc3y MJaWE73z/FC/UqGjDK9nw9IsXWjoCAF9Ugt9mlnTV/4H6S4lUJoFryDx1XFgG4o= =IH9z -----END PGP SIGNATURE----- --LQksG6bCIzRHxTLp-- -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752101AbdJPJ0d (ORCPT ); Mon, 16 Oct 2017 05:26:33 -0400 Received: from mga05.intel.com ([192.55.52.43]:14032 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751776AbdJPJ0b (ORCPT ); Mon, 16 Oct 2017 05:26:31 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,386,1503385200"; d="scan'208";a="163576708" From: changbin.du@intel.com To: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Changbin Du Subject: [PATCH 0/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Date: Mon, 16 Oct 2017 17:19:15 +0800 Message-Id: <1508145557-9944-1-git-send-email-changbin.du@intel.com> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Changbin Du The first one introduce new interfaces, the second one kills naming confusion. The aim is to remove duplicated code and simplify transparent huge page allocation. Changbin Du (2): mm, thp: introduce dedicated transparent huge page allocation interfaces mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Documentation/vm/hugetlbfs_reserv.txt | 4 +-- include/linux/gfp.h | 4 --- include/linux/huge_mm.h | 15 ++++++++-- include/linux/hugetlb.h | 2 +- include/linux/migrate.h | 14 ++++----- include/linux/mm.h | 8 +++--- mm/huge_memory.c | 54 +++++++++++++++++++++++++++++------ mm/hugetlb.c | 14 ++++----- mm/khugepaged.c | 11 ++----- mm/mempolicy.c | 10 ++----- mm/migrate.c | 12 +++----- mm/page_alloc.c | 10 +++---- mm/shmem.c | 6 ++-- mm/swap.c | 2 +- mm/userfaultfd.c | 2 +- 15 files changed, 95 insertions(+), 73 deletions(-) -- 2.7.4 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752123AbdJPJ0i (ORCPT ); Mon, 16 Oct 2017 05:26:38 -0400 Received: from mga05.intel.com ([192.55.52.43]:14032 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751776AbdJPJ0e (ORCPT ); Mon, 16 Oct 2017 05:26:34 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,386,1503385200"; d="scan'208";a="163576724" From: changbin.du@intel.com To: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Changbin Du Subject: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Date: Mon, 16 Oct 2017 17:19:16 +0800 Message-Id: <1508145557-9944-2-git-send-email-changbin.du@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1508145557-9944-1-git-send-email-changbin.du@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Changbin Du This patch introduced 4 new interfaces to allocate a prepared transparent huge page. - alloc_transhuge_page_vma - alloc_transhuge_page_nodemask - alloc_transhuge_page_node - alloc_transhuge_page The aim is to remove duplicated code and simplify transparent huge page allocation. These are similar to alloc_hugepage_xxx which are for hugetlbfs pages. This patch does below changes: - define alloc_transhuge_page_xxx interfaces - apply them to all existing code - declare prep_transhuge_page as static since no others use it - remove alloc_hugepage_vma definition since it no longer has users Signed-off-by: Changbin Du --- include/linux/gfp.h | 4 ---- include/linux/huge_mm.h | 13 ++++++++++++- include/linux/migrate.h | 14 +++++--------- mm/huge_memory.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- mm/khugepaged.c | 11 ++--------- mm/mempolicy.c | 10 +++------- mm/migrate.c | 12 ++++-------- mm/shmem.c | 6 ++---- 8 files changed, 71 insertions(+), 49 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index f780718..855c72e 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -507,15 +507,11 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, struct vm_area_struct *vma, unsigned long addr, int node, bool hugepage); -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ - alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) #else #define alloc_pages(gfp_mask, order) \ alloc_pages_node(numa_node_id(), gfp_mask, order) #define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ alloc_pages(gfp_mask, order) -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ - alloc_pages(gfp_mask, order) #endif #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) #define alloc_page_vma(gfp_mask, vma, addr) \ diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 14bc21c..1dd2c33 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); -extern void prep_transhuge_page(struct page *page); extern void free_transhuge_page(struct page *page); +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, + struct vm_area_struct *vma, unsigned long addr); +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, + int preferred_nid, nodemask_t *nmask); + +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gfp_mask) +{ + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); +} + +struct page *alloc_transhuge_page(gfp_t gfp_mask); + bool can_split_huge_page(struct page *page, int *pextra_pins); int split_huge_page_to_list(struct page *page, struct list_head *list); static inline int split_huge_page(struct page *page) diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 643c7ae..70a00f3 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct page *page, return alloc_huge_page_nodemask(page_hstate(compound_head(page)), preferred_nid, nodemask); - if (thp_migration_supported() && PageTransHuge(page)) { - order = HPAGE_PMD_ORDER; - gfp_mask |= GFP_TRANSHUGE; - } - if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) gfp_mask |= __GFP_HIGHMEM; - new_page = __alloc_pages_nodemask(gfp_mask, order, + if (thp_migration_supported() && PageTransHuge(page)) + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, + preferred_nid, nodemask); + else + return __alloc_pages_nodemask(gfp_mask, order, preferred_nid, nodemask); - - if (new_page && PageTransHuge(page)) - prep_transhuge_page(new_page); return new_page; } diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 269b5df..e267488 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(struct page *page) return (struct list_head *)&page[2].mapping; } -void prep_transhuge_page(struct page *page) +static void prep_transhuge_page(struct page *page) { /* * we use page->mapping and page->indexlru in second tail page @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); } +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, + struct vm_area_struct *vma, unsigned long addr) +{ + struct page *page; + + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, + vma, addr, numa_node_id(), true); + if (unlikely(!page)) + return NULL; + prep_transhuge_page(page); + return page; +} + +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, + int preferred_nid, nodemask_t *nmask) +{ + struct page *page; + + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, + preferred_nid, nmask); + if (unlikely(!page)) + return NULL; + prep_transhuge_page(page); + return page; +} + +struct page *alloc_transhuge_page(gfp_t gfp_mask) +{ + struct page *page; + + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); + + page = alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); + if (unlikely(!page)) + return NULL; + prep_transhuge_page(page); + return page; +} + unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, loff_t off, unsigned long flags, unsigned long size) { @@ -719,12 +758,11 @@ int do_huge_pmd_anonymous_page(struct vm_fault *vmf) return ret; } gfp = alloc_hugepage_direct_gfpmask(vma); - page = alloc_hugepage_vma(gfp, vma, haddr, HPAGE_PMD_ORDER); + page = alloc_transhuge_page_vma(gfp, vma, haddr); if (unlikely(!page)) { count_vm_event(THP_FAULT_FALLBACK); return VM_FAULT_FALLBACK; } - prep_transhuge_page(page); return __do_huge_pmd_anonymous_page(vmf, page, gfp); } @@ -1288,13 +1326,11 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) if (transparent_hugepage_enabled(vma) && !transparent_hugepage_debug_cow()) { huge_gfp = alloc_hugepage_direct_gfpmask(vma); - new_page = alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDER); + new_page = alloc_transhuge_page_vma(huge_gfp, vma, haddr); } else new_page = NULL; - if (likely(new_page)) { - prep_transhuge_page(new_page); - } else { + if (unlikely(!new_page)) { if (!page) { split_huge_pmd(vma, vmf->pmd, vmf->address); ret |= VM_FAULT_FALLBACK; diff --git a/mm/khugepaged.c b/mm/khugepaged.c index c01f177..d17a694 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -745,14 +745,13 @@ khugepaged_alloc_page(struct page **hpage, gfp_t gfp, int node) { VM_BUG_ON_PAGE(*hpage, *hpage); - *hpage = __alloc_pages_node(node, gfp, HPAGE_PMD_ORDER); + *hpage = alloc_transhuge_page_node(node, gfp); if (unlikely(!*hpage)) { count_vm_event(THP_COLLAPSE_ALLOC_FAILED); *hpage = ERR_PTR(-ENOMEM); return NULL; } - prep_transhuge_page(*hpage); count_vm_event(THP_COLLAPSE_ALLOC); return *hpage; } @@ -764,13 +763,7 @@ static int khugepaged_find_target_node(void) static inline struct page *alloc_khugepaged_hugepage(void) { - struct page *page; - - page = alloc_pages(alloc_hugepage_khugepaged_gfpmask(), - HPAGE_PMD_ORDER); - if (page) - prep_transhuge_page(page); - return page; + return alloc_transhuge_page(alloc_hugepage_khugepaged_gfpmask()); } static struct page *khugepaged_alloc_hugepage(bool *wait) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index a2af6d5..aa24285 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -949,12 +949,10 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x else if (thp_migration_supported() && PageTransHuge(page)) { struct page *thp; - thp = alloc_pages_node(node, - (GFP_TRANSHUGE | __GFP_THISNODE), - HPAGE_PMD_ORDER); + thp = alloc_transhuge_page_node(node, + (GFP_TRANSHUGE | __GFP_THISNODE)); if (!thp) return NULL; - prep_transhuge_page(thp); return thp; } else return __alloc_pages_node(node, GFP_HIGHUSER_MOVABLE | @@ -1125,11 +1123,9 @@ static struct page *new_page(struct page *page, unsigned long start, int **x) } else if (thp_migration_supported() && PageTransHuge(page)) { struct page *thp; - thp = alloc_hugepage_vma(GFP_TRANSHUGE, vma, address, - HPAGE_PMD_ORDER); + thp = alloc_transhuge_page_vma(GFP_TRANSHUGE, vma, address); if (!thp) return NULL; - prep_transhuge_page(thp); return thp; } /* diff --git a/mm/migrate.c b/mm/migrate.c index e00814c..7f0486f 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1472,12 +1472,10 @@ static struct page *new_page_node(struct page *p, unsigned long private, else if (thp_migration_supported() && PageTransHuge(p)) { struct page *thp; - thp = alloc_pages_node(pm->node, - (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM, - HPAGE_PMD_ORDER); + thp = alloc_transhuge_page_node(pm->node, + (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM); if (!thp) return NULL; - prep_transhuge_page(thp); return thp; } else return __alloc_pages_node(pm->node, @@ -2017,12 +2015,10 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, if (numamigrate_update_ratelimit(pgdat, HPAGE_PMD_NR)) goto out_dropref; - new_page = alloc_pages_node(node, - (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE), - HPAGE_PMD_ORDER); + new_page = alloc_transhuge_page_node(node, + (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE)); if (!new_page) goto out_fail; - prep_transhuge_page(new_page); isolated = numamigrate_isolate_page(pgdat, page); if (!isolated) { diff --git a/mm/shmem.c b/mm/shmem.c index 07a1d22..52468f7 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1444,11 +1444,9 @@ static struct page *shmem_alloc_hugepage(gfp_t gfp, rcu_read_unlock(); shmem_pseudo_vma_init(&pvma, info, hindex); - page = alloc_pages_vma(gfp | __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN, - HPAGE_PMD_ORDER, &pvma, 0, numa_node_id(), true); + gfp |= __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN; + page = alloc_transhuge_page_vma(gfp, &pvma, 0); shmem_pseudo_vma_destroy(&pvma); - if (page) - prep_transhuge_page(page); return page; } -- 2.7.4 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752132AbdJPJ0t (ORCPT ); Mon, 16 Oct 2017 05:26:49 -0400 Received: from mga05.intel.com ([192.55.52.43]:14032 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752105AbdJPJ0h (ORCPT ); Mon, 16 Oct 2017 05:26:37 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,386,1503385200"; d="scan'208";a="163576740" From: changbin.du@intel.com To: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Changbin Du Subject: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Date: Mon, 16 Oct 2017 17:19:17 +0800 Message-Id: <1508145557-9944-3-git-send-email-changbin.du@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1508145557-9944-1-git-send-email-changbin.du@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Changbin Du The current name free_{huge,transhuge}_page are paired with alloc_{huge,transhuge}_page functions, but the actual page free function is still free_page() which will indirectly call free_{huge,transhuge}_page. So this patch removes this confusion by renaming all the compound page dtors. Signed-off-by: Changbin Du --- Documentation/vm/hugetlbfs_reserv.txt | 4 ++-- include/linux/huge_mm.h | 2 +- include/linux/hugetlb.h | 2 +- include/linux/mm.h | 8 ++++---- mm/huge_memory.c | 4 ++-- mm/hugetlb.c | 14 +++++++------- mm/page_alloc.c | 10 +++++----- mm/swap.c | 2 +- mm/userfaultfd.c | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Documentation/vm/hugetlbfs_reserv.txt b/Documentation/vm/hugetlbfs_reserv.txt index 9aca09a..b3ffa3e 100644 --- a/Documentation/vm/hugetlbfs_reserv.txt +++ b/Documentation/vm/hugetlbfs_reserv.txt @@ -238,7 +238,7 @@ to the global reservation count (resv_huge_pages). Freeing Huge Pages ------------------ -Huge page freeing is performed by the routine free_huge_page(). This routine +Huge page freeing is performed by the routine huge_page_dtor(). This routine is the destructor for hugetlbfs compound pages. As a result, it is only passed a pointer to the page struct. When a huge page is freed, reservation accounting may need to be performed. This would be the case if the page was @@ -468,7 +468,7 @@ However, there are several instances where errors are encountered after a huge page is allocated but before it is instantiated. In this case, the page allocation has consumed the reservation and made the appropriate subpool, reservation map and global count adjustments. If the page is freed at this -time (before instantiation and clearing of PagePrivate), then free_huge_page +time (before instantiation and clearing of PagePrivate), then huge_page_dtor will increment the global reservation count. However, the reservation map indicates the reservation was consumed. This resulting inconsistent state will cause the 'leak' of a reserved huge page. The global reserve count will diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 1dd2c33..40ae3058 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -130,7 +130,7 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); -extern void free_transhuge_page(struct page *page); +extern void transhuge_page_dtor(struct page *page); struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, struct vm_area_struct *vma, unsigned long addr); diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 8bbbd37..24492c5 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -118,7 +118,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, long freed); bool isolate_huge_page(struct page *page, struct list_head *list); void putback_active_hugepage(struct page *page); -void free_huge_page(struct page *page); +void huge_page_dtor(struct page *page); void hugetlb_fix_reserve_counts(struct inode *inode); extern struct mutex *hugetlb_fault_mutex_table; u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, diff --git a/include/linux/mm.h b/include/linux/mm.h index 065d99d..adfa906 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -616,7 +616,7 @@ void split_page(struct page *page, unsigned int order); * prototype for that function and accessor functions. * These are _only_ valid on the head of a compound page. */ -typedef void compound_page_dtor(struct page *); +typedef void compound_page_dtor_t(struct page *); /* Keep the enum in sync with compound_page_dtors array in mm/page_alloc.c */ enum compound_dtor_id { @@ -630,7 +630,7 @@ enum compound_dtor_id { #endif NR_COMPOUND_DTORS, }; -extern compound_page_dtor * const compound_page_dtors[]; +extern compound_page_dtor_t * const compound_page_dtors[]; static inline void set_compound_page_dtor(struct page *page, enum compound_dtor_id compound_dtor) @@ -639,7 +639,7 @@ static inline void set_compound_page_dtor(struct page *page, page[1].compound_dtor = compound_dtor; } -static inline compound_page_dtor *get_compound_page_dtor(struct page *page) +static inline compound_page_dtor_t *get_compound_page_dtor(struct page *page) { VM_BUG_ON_PAGE(page[1].compound_dtor >= NR_COMPOUND_DTORS, page); return compound_page_dtors[page[1].compound_dtor]; @@ -657,7 +657,7 @@ static inline void set_compound_order(struct page *page, unsigned int order) page[1].compound_order = order; } -void free_compound_page(struct page *page); +void compound_page_dtor(struct page *page); #ifdef CONFIG_MMU /* diff --git a/mm/huge_memory.c b/mm/huge_memory.c index e267488..a01125b 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2717,7 +2717,7 @@ fail: if (mapping) return ret; } -void free_transhuge_page(struct page *page) +void transhuge_page_dtor(struct page *page) { struct pglist_data *pgdata = NODE_DATA(page_to_nid(page)); unsigned long flags; @@ -2728,7 +2728,7 @@ void free_transhuge_page(struct page *page) list_del(page_deferred_list(page)); } spin_unlock_irqrestore(&pgdata->split_queue_lock, flags); - free_compound_page(page); + compound_page_dtor(page); } void deferred_split_huge_page(struct page *page) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 424b0ef..1af2c4e7 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1250,7 +1250,7 @@ static void clear_page_huge_active(struct page *page) ClearPagePrivate(&page[1]); } -void free_huge_page(struct page *page) +void huge_page_dtor(struct page *page) { /* * Can't pass hstate in here because it is called from the @@ -1363,7 +1363,7 @@ int PageHeadHuge(struct page *page_head) if (!PageHead(page_head)) return 0; - return get_compound_page_dtor(page_head) == free_huge_page; + return get_compound_page_dtor(page_head) == huge_page_dtor; } pgoff_t __basepage_index(struct page *page) @@ -1932,11 +1932,11 @@ static long vma_add_reservation(struct hstate *h, * specific error paths, a huge page was allocated (via alloc_huge_page) * and is about to be freed. If a reservation for the page existed, * alloc_huge_page would have consumed the reservation and set PagePrivate - * in the newly allocated page. When the page is freed via free_huge_page, + * in the newly allocated page. When the page is freed via huge_page_dtor, * the global reservation count will be incremented if PagePrivate is set. - * However, free_huge_page can not adjust the reserve map. Adjust the + * However, huge_page_dtor can not adjust the reserve map. Adjust the * reserve map here to be consistent with global reserve count adjustments - * to be made by free_huge_page. + * to be made by huge_page_dtor. */ static void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma, unsigned long address, @@ -1950,7 +1950,7 @@ static void restore_reserve_on_error(struct hstate *h, * Rare out of memory condition in reserve map * manipulation. Clear PagePrivate so that * global reserve count will not be incremented - * by free_huge_page. This will make it appear + * by huge_page_dtor. This will make it appear * as though the reservation for this page was * consumed. This may prevent the task from * faulting in the page at a later time. This @@ -2304,7 +2304,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, while (count > persistent_huge_pages(h)) { /* * If this allocation races such that we no longer need the - * page, free_huge_page will handle it by freeing the page + * page, huge_page_dtor will handle it by freeing the page * and reducing the surplus. */ spin_unlock(&hugetlb_lock); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 77e4d3c..b31205c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -248,14 +248,14 @@ char * const migratetype_names[MIGRATE_TYPES] = { #endif }; -compound_page_dtor * const compound_page_dtors[] = { +compound_page_dtor_t * const compound_page_dtors[] = { NULL, - free_compound_page, + compound_page_dtor, #ifdef CONFIG_HUGETLB_PAGE - free_huge_page, + huge_page_dtor, #endif #ifdef CONFIG_TRANSPARENT_HUGEPAGE - free_transhuge_page, + transhuge_page_dtor, #endif }; @@ -586,7 +586,7 @@ static void bad_page(struct page *page, const char *reason, * This usage means that zero-order pages may not be compound. */ -void free_compound_page(struct page *page) +void compound_page_dtor(struct page *page) { __free_pages_ok(page, compound_order(page)); } diff --git a/mm/swap.c b/mm/swap.c index a77d68f..8f98caf 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -81,7 +81,7 @@ static void __put_single_page(struct page *page) static void __put_compound_page(struct page *page) { - compound_page_dtor *dtor; + compound_page_dtor_t *dtor; /* * __page_cache_release() is supposed to be called for thp, not for diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 8119270..91d9045 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -323,7 +323,7 @@ static __always_inline ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, * map of a private mapping, the map was modified to indicate * the reservation was consumed when the page was allocated. * We clear the PagePrivate flag now so that the global - * reserve count will not be incremented in free_huge_page. + * reserve count will not be incremented in huge_page_dtor. * The reservation map will still indicate the reservation * was consumed and possibly prevent later page allocation. * This is better than leaking a global reservation. If no -- 2.7.4 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934252AbdJQIIW (ORCPT ); Tue, 17 Oct 2017 04:08:22 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:49996 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934238AbdJQIIS (ORCPT ); Tue, 17 Oct 2017 04:08:18 -0400 Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces To: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org From: Anshuman Khandual Date: Tue, 17 Oct 2017 13:38:07 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-TM-AS-MML: disable x-cbid: 17101708-0008-0000-0000-000004A08B79 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17101708-0009-0000-0000-00001E32D219 Message-Id: <66a3f340-ff44-efad-48ad-a95554938a29@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-10-17_05:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1710170113 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 10/16/2017 02:49 PM, changbin.du@intel.com wrote: > From: Changbin Du > > This patch introduced 4 new interfaces to allocate a prepared > transparent huge page. > - alloc_transhuge_page_vma > - alloc_transhuge_page_nodemask > - alloc_transhuge_page_node > - alloc_transhuge_page > If we are trying to match HugeTLB helpers, then it should have format something like alloc_transhugepage_xxx instead of alloc_transhuge_page_XXX. But I think its okay. > The aim is to remove duplicated code and simplify transparent > huge page allocation. These are similar to alloc_hugepage_xxx > which are for hugetlbfs pages. This patch does below changes: > - define alloc_transhuge_page_xxx interfaces > - apply them to all existing code > - declare prep_transhuge_page as static since no others use it > - remove alloc_hugepage_vma definition since it no longer has users > > Signed-off-by: Changbin Du > --- > include/linux/gfp.h | 4 ---- > include/linux/huge_mm.h | 13 ++++++++++++- > include/linux/migrate.h | 14 +++++--------- > mm/huge_memory.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- > mm/khugepaged.c | 11 ++--------- > mm/mempolicy.c | 10 +++------- > mm/migrate.c | 12 ++++-------- > mm/shmem.c | 6 ++---- > 8 files changed, 71 insertions(+), 49 deletions(-) > > diff --git a/include/linux/gfp.h b/include/linux/gfp.h > index f780718..855c72e 100644 > --- a/include/linux/gfp.h > +++ b/include/linux/gfp.h > @@ -507,15 +507,11 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) > extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, > struct vm_area_struct *vma, unsigned long addr, > int node, bool hugepage); > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > - alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) > #else > #define alloc_pages(gfp_mask, order) \ > alloc_pages_node(numa_node_id(), gfp_mask, order) > #define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ > alloc_pages(gfp_mask, order) > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > - alloc_pages(gfp_mask, order) > #endif > #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) > #define alloc_page_vma(gfp_mask, vma, addr) \ > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 14bc21c..1dd2c33 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > unsigned long flags); > > -extern void prep_transhuge_page(struct page *page); > extern void free_transhuge_page(struct page *page); > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr); > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask); Would not they require 'extern' here ? > + > +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gfp_mask) > +{ > + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); > +} > + > +struct page *alloc_transhuge_page(gfp_t gfp_mask); > + > bool can_split_huge_page(struct page *page, int *pextra_pins); > int split_huge_page_to_list(struct page *page, struct list_head *list); > static inline int split_huge_page(struct page *page) > diff --git a/include/linux/migrate.h b/include/linux/migrate.h > index 643c7ae..70a00f3 100644 > --- a/include/linux/migrate.h > +++ b/include/linux/migrate.h > @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct page *page, > return alloc_huge_page_nodemask(page_hstate(compound_head(page)), > preferred_nid, nodemask); > > - if (thp_migration_supported() && PageTransHuge(page)) { > - order = HPAGE_PMD_ORDER; > - gfp_mask |= GFP_TRANSHUGE; > - } > - > if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) > gfp_mask |= __GFP_HIGHMEM; > > - new_page = __alloc_pages_nodemask(gfp_mask, order, > + if (thp_migration_supported() && PageTransHuge(page)) > + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, > + preferred_nid, nodemask); > + else > + return __alloc_pages_nodemask(gfp_mask, order, > preferred_nid, nodemask); > - > - if (new_page && PageTransHuge(page)) > - prep_transhuge_page(new_page); This makes sense, calling prep_transhuge_page() inside the function alloc_transhuge_page_nodemask() is better I guess. > > return new_page; > } > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index 269b5df..e267488 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(struct page *page) > return (struct list_head *)&page[2].mapping; > } > > -void prep_transhuge_page(struct page *page) > +static void prep_transhuge_page(struct page *page) Right. It wont be used outside huge page allocation context and you have already mentioned about it. > { > /* > * we use page->mapping and page->indexlru in second tail page > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > } > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr) > +{ > + struct page *page; > + > + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + vma, addr, numa_node_id(), true); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} __GFP_COMP and HPAGE_PMD_ORDER are the minimum flags which will be used for huge page allocation and preparation. Any thing else depending upon the context will be passed by the caller. Makes sense. > + > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask) > +{ > + struct page *page; > + > + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + preferred_nid, nmask); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + Same here. > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > +{ > + struct page *page; > + > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); You expect the caller to provide __GFP_COMP, why ? You are anyways providing it later. From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934499AbdJQIhU (ORCPT ); Tue, 17 Oct 2017 04:37:20 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:52032 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934462AbdJQIhJ (ORCPT ); Tue, 17 Oct 2017 04:37:09 -0400 Subject: Re: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor To: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-3-git-send-email-changbin.du@intel.com> Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org From: Anshuman Khandual Date: Tue, 17 Oct 2017 14:06:58 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: <1508145557-9944-3-git-send-email-changbin.du@intel.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-TM-AS-MML: disable x-cbid: 17101708-0012-0000-0000-000005828BCD X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17101708-0013-0000-0000-000018FCDC25 Message-Id: <4911ff99-ac77-0344-8696-a15ca9f3e763@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-10-17_06:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1710170120 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 10/16/2017 02:49 PM, changbin.du@intel.com wrote: > From: Changbin Du > > The current name free_{huge,transhuge}_page are paired with > alloc_{huge,transhuge}_page functions, but the actual page free > function is still free_page() which will indirectly call > free_{huge,transhuge}_page. So this patch removes this confusion > by renaming all the compound page dtors. > > Signed-off-by: Changbin Du > --- > Documentation/vm/hugetlbfs_reserv.txt | 4 ++-- > include/linux/huge_mm.h | 2 +- > include/linux/hugetlb.h | 2 +- > include/linux/mm.h | 8 ++++---- > mm/huge_memory.c | 4 ++-- > mm/hugetlb.c | 14 +++++++------- > mm/page_alloc.c | 10 +++++----- > mm/swap.c | 2 +- > mm/userfaultfd.c | 2 +- > 9 files changed, 24 insertions(+), 24 deletions(-) > > diff --git a/Documentation/vm/hugetlbfs_reserv.txt b/Documentation/vm/hugetlbfs_reserv.txt > index 9aca09a..b3ffa3e 100644 > --- a/Documentation/vm/hugetlbfs_reserv.txt > +++ b/Documentation/vm/hugetlbfs_reserv.txt > @@ -238,7 +238,7 @@ to the global reservation count (resv_huge_pages). > > Freeing Huge Pages > ------------------ > -Huge page freeing is performed by the routine free_huge_page(). This routine > +Huge page freeing is performed by the routine huge_page_dtor(). This routine > is the destructor for hugetlbfs compound pages. As a result, it is only > passed a pointer to the page struct. When a huge page is freed, reservation > accounting may need to be performed. This would be the case if the page was > @@ -468,7 +468,7 @@ However, there are several instances where errors are encountered after a huge > page is allocated but before it is instantiated. In this case, the page > allocation has consumed the reservation and made the appropriate subpool, > reservation map and global count adjustments. If the page is freed at this > -time (before instantiation and clearing of PagePrivate), then free_huge_page > +time (before instantiation and clearing of PagePrivate), then huge_page_dtor > will increment the global reservation count. However, the reservation map > indicates the reservation was consumed. This resulting inconsistent state > will cause the 'leak' of a reserved huge page. The global reserve count will > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 1dd2c33..40ae3058 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -130,7 +130,7 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > unsigned long flags); > > -extern void free_transhuge_page(struct page *page); > +extern void transhuge_page_dtor(struct page *page); > > struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > struct vm_area_struct *vma, unsigned long addr); > diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h > index 8bbbd37..24492c5 100644 > --- a/include/linux/hugetlb.h > +++ b/include/linux/hugetlb.h > @@ -118,7 +118,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, > long freed); > bool isolate_huge_page(struct page *page, struct list_head *list); > void putback_active_hugepage(struct page *page); > -void free_huge_page(struct page *page); > +void huge_page_dtor(struct page *page); > void hugetlb_fix_reserve_counts(struct inode *inode); > extern struct mutex *hugetlb_fault_mutex_table; > u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 065d99d..adfa906 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -616,7 +616,7 @@ void split_page(struct page *page, unsigned int order); > * prototype for that function and accessor functions. > * These are _only_ valid on the head of a compound page. > */ > -typedef void compound_page_dtor(struct page *); > +typedef void compound_page_dtor_t(struct page *); Why changing this ? I understand _t kind of specifies it more like a type def but this patch is just to rename the compound page destructor functions. Not sure we should change datatype here as well in this patch. > > /* Keep the enum in sync with compound_page_dtors array in mm/page_alloc.c */ > enum compound_dtor_id { > @@ -630,7 +630,7 @@ enum compound_dtor_id { > #endif > NR_COMPOUND_DTORS, > }; > -extern compound_page_dtor * const compound_page_dtors[]; > +extern compound_page_dtor_t * const compound_page_dtors[]; > > static inline void set_compound_page_dtor(struct page *page, > enum compound_dtor_id compound_dtor) > @@ -639,7 +639,7 @@ static inline void set_compound_page_dtor(struct page *page, > page[1].compound_dtor = compound_dtor; > } > > -static inline compound_page_dtor *get_compound_page_dtor(struct page *page) > +static inline compound_page_dtor_t *get_compound_page_dtor(struct page *page) Which is adding these kind of changes to the patch without having a corresponding description in the commit message. > { > VM_BUG_ON_PAGE(page[1].compound_dtor >= NR_COMPOUND_DTORS, page); > return compound_page_dtors[page[1].compound_dtor]; > @@ -657,7 +657,7 @@ static inline void set_compound_order(struct page *page, unsigned int order) > page[1].compound_order = order; > } > > -void free_compound_page(struct page *page); > +void compound_page_dtor(struct page *page); > > #ifdef CONFIG_MMU > /* > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index e267488..a01125b 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -2717,7 +2717,7 @@ fail: if (mapping) > return ret; > } > > -void free_transhuge_page(struct page *page) > +void transhuge_page_dtor(struct page *page) > { > struct pglist_data *pgdata = NODE_DATA(page_to_nid(page)); > unsigned long flags; > @@ -2728,7 +2728,7 @@ void free_transhuge_page(struct page *page) > list_del(page_deferred_list(page)); > } > spin_unlock_irqrestore(&pgdata->split_queue_lock, flags); > - free_compound_page(page); > + compound_page_dtor(page); > } > > void deferred_split_huge_page(struct page *page) > diff --git a/mm/hugetlb.c b/mm/hugetlb.c > index 424b0ef..1af2c4e7 100644 > --- a/mm/hugetlb.c > +++ b/mm/hugetlb.c > @@ -1250,7 +1250,7 @@ static void clear_page_huge_active(struct page *page) > ClearPagePrivate(&page[1]); > } > > -void free_huge_page(struct page *page) > +void huge_page_dtor(struct page *page) > { > /* > * Can't pass hstate in here because it is called from the > @@ -1363,7 +1363,7 @@ int PageHeadHuge(struct page *page_head) > if (!PageHead(page_head)) > return 0; > > - return get_compound_page_dtor(page_head) == free_huge_page; > + return get_compound_page_dtor(page_head) == huge_page_dtor; > } > > pgoff_t __basepage_index(struct page *page) > @@ -1932,11 +1932,11 @@ static long vma_add_reservation(struct hstate *h, > * specific error paths, a huge page was allocated (via alloc_huge_page) > * and is about to be freed. If a reservation for the page existed, > * alloc_huge_page would have consumed the reservation and set PagePrivate > - * in the newly allocated page. When the page is freed via free_huge_page, > + * in the newly allocated page. When the page is freed via huge_page_dtor, > * the global reservation count will be incremented if PagePrivate is set. > - * However, free_huge_page can not adjust the reserve map. Adjust the > + * However, huge_page_dtor can not adjust the reserve map. Adjust the > * reserve map here to be consistent with global reserve count adjustments > - * to be made by free_huge_page. > + * to be made by huge_page_dtor. > */ > static void restore_reserve_on_error(struct hstate *h, > struct vm_area_struct *vma, unsigned long address, > @@ -1950,7 +1950,7 @@ static void restore_reserve_on_error(struct hstate *h, > * Rare out of memory condition in reserve map > * manipulation. Clear PagePrivate so that > * global reserve count will not be incremented > - * by free_huge_page. This will make it appear > + * by huge_page_dtor. This will make it appear > * as though the reservation for this page was > * consumed. This may prevent the task from > * faulting in the page at a later time. This > @@ -2304,7 +2304,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, > while (count > persistent_huge_pages(h)) { > /* > * If this allocation races such that we no longer need the > - * page, free_huge_page will handle it by freeing the page > + * page, huge_page_dtor will handle it by freeing the page > * and reducing the surplus. > */ > spin_unlock(&hugetlb_lock); > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > index 77e4d3c..b31205c 100644 > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -248,14 +248,14 @@ char * const migratetype_names[MIGRATE_TYPES] = { > #endif > }; > > -compound_page_dtor * const compound_page_dtors[] = { > +compound_page_dtor_t * const compound_page_dtors[] = { Adding this chunk as well. > NULL, > - free_compound_page, > + compound_page_dtor, > #ifdef CONFIG_HUGETLB_PAGE > - free_huge_page, > + huge_page_dtor, > #endif > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - free_transhuge_page, > + transhuge_page_dtor, > #endif > }; Having *dtor* in the destructor functions for the huge pages (all of them) actually makes sense. It wont be confused with a lot other free_* functions and some of them dealing with THP/HugeTLB as well. > > @@ -586,7 +586,7 @@ static void bad_page(struct page *page, const char *reason, > * This usage means that zero-order pages may not be compound. > */ > > -void free_compound_page(struct page *page) > +void compound_page_dtor(struct page *page) > { > __free_pages_ok(page, compound_order(page)); > } > diff --git a/mm/swap.c b/mm/swap.c > index a77d68f..8f98caf 100644 > --- a/mm/swap.c > +++ b/mm/swap.c > @@ -81,7 +81,7 @@ static void __put_single_page(struct page *page) > > static void __put_compound_page(struct page *page) > { > - compound_page_dtor *dtor; > + compound_page_dtor_t *dtor; If the typedef change needs to be retained then the commit message must include a line. From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760929AbdJQKU7 (ORCPT ); Tue, 17 Oct 2017 06:20:59 -0400 Received: from mx2.suse.de ([195.135.220.15]:48062 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756931AbdJQKUz (ORCPT ); Tue, 17 Oct 2017 06:20:55 -0400 Date: Tue, 17 Oct 2017 12:20:52 +0200 From: Michal Hocko To: changbin.du@intel.com Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [CC Kirill] On Mon 16-10-17 17:19:16, changbin.du@intel.com wrote: > From: Changbin Du > > This patch introduced 4 new interfaces to allocate a prepared > transparent huge page. > - alloc_transhuge_page_vma > - alloc_transhuge_page_nodemask > - alloc_transhuge_page_node > - alloc_transhuge_page > > The aim is to remove duplicated code and simplify transparent > huge page allocation. These are similar to alloc_hugepage_xxx > which are for hugetlbfs pages. This patch does below changes: > - define alloc_transhuge_page_xxx interfaces > - apply them to all existing code > - declare prep_transhuge_page as static since no others use it > - remove alloc_hugepage_vma definition since it no longer has users So what exactly is the advantage of the new API? The diffstat doesn't sound very convincing to me. > Signed-off-by: Changbin Du > --- > include/linux/gfp.h | 4 ---- > include/linux/huge_mm.h | 13 ++++++++++++- > include/linux/migrate.h | 14 +++++--------- > mm/huge_memory.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- > mm/khugepaged.c | 11 ++--------- > mm/mempolicy.c | 10 +++------- > mm/migrate.c | 12 ++++-------- > mm/shmem.c | 6 ++---- > 8 files changed, 71 insertions(+), 49 deletions(-) > > diff --git a/include/linux/gfp.h b/include/linux/gfp.h > index f780718..855c72e 100644 > --- a/include/linux/gfp.h > +++ b/include/linux/gfp.h > @@ -507,15 +507,11 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) > extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, > struct vm_area_struct *vma, unsigned long addr, > int node, bool hugepage); > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > - alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) > #else > #define alloc_pages(gfp_mask, order) \ > alloc_pages_node(numa_node_id(), gfp_mask, order) > #define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ > alloc_pages(gfp_mask, order) > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > - alloc_pages(gfp_mask, order) > #endif > #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) > #define alloc_page_vma(gfp_mask, vma, addr) \ > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 14bc21c..1dd2c33 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > unsigned long flags); > > -extern void prep_transhuge_page(struct page *page); > extern void free_transhuge_page(struct page *page); > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr); > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask); > + > +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gfp_mask) > +{ > + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); > +} > + > +struct page *alloc_transhuge_page(gfp_t gfp_mask); > + > bool can_split_huge_page(struct page *page, int *pextra_pins); > int split_huge_page_to_list(struct page *page, struct list_head *list); > static inline int split_huge_page(struct page *page) > diff --git a/include/linux/migrate.h b/include/linux/migrate.h > index 643c7ae..70a00f3 100644 > --- a/include/linux/migrate.h > +++ b/include/linux/migrate.h > @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct page *page, > return alloc_huge_page_nodemask(page_hstate(compound_head(page)), > preferred_nid, nodemask); > > - if (thp_migration_supported() && PageTransHuge(page)) { > - order = HPAGE_PMD_ORDER; > - gfp_mask |= GFP_TRANSHUGE; > - } > - > if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) > gfp_mask |= __GFP_HIGHMEM; > > - new_page = __alloc_pages_nodemask(gfp_mask, order, > + if (thp_migration_supported() && PageTransHuge(page)) > + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, > + preferred_nid, nodemask); > + else > + return __alloc_pages_nodemask(gfp_mask, order, > preferred_nid, nodemask); > - > - if (new_page && PageTransHuge(page)) > - prep_transhuge_page(new_page); > > return new_page; > } > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index 269b5df..e267488 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(struct page *page) > return (struct list_head *)&page[2].mapping; > } > > -void prep_transhuge_page(struct page *page) > +static void prep_transhuge_page(struct page *page) > { > /* > * we use page->mapping and page->indexlru in second tail page > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > } > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr) > +{ > + struct page *page; > + > + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + vma, addr, numa_node_id(), true); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask) > +{ > + struct page *page; > + > + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + preferred_nid, nmask); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > +{ > + struct page *page; > + > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); > + > + page = alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, > loff_t off, unsigned long flags, unsigned long size) > { > @@ -719,12 +758,11 @@ int do_huge_pmd_anonymous_page(struct vm_fault *vmf) > return ret; > } > gfp = alloc_hugepage_direct_gfpmask(vma); > - page = alloc_hugepage_vma(gfp, vma, haddr, HPAGE_PMD_ORDER); > + page = alloc_transhuge_page_vma(gfp, vma, haddr); > if (unlikely(!page)) { > count_vm_event(THP_FAULT_FALLBACK); > return VM_FAULT_FALLBACK; > } > - prep_transhuge_page(page); > return __do_huge_pmd_anonymous_page(vmf, page, gfp); > } > > @@ -1288,13 +1326,11 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) > if (transparent_hugepage_enabled(vma) && > !transparent_hugepage_debug_cow()) { > huge_gfp = alloc_hugepage_direct_gfpmask(vma); > - new_page = alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDER); > + new_page = alloc_transhuge_page_vma(huge_gfp, vma, haddr); > } else > new_page = NULL; > > - if (likely(new_page)) { > - prep_transhuge_page(new_page); > - } else { > + if (unlikely(!new_page)) { > if (!page) { > split_huge_pmd(vma, vmf->pmd, vmf->address); > ret |= VM_FAULT_FALLBACK; > diff --git a/mm/khugepaged.c b/mm/khugepaged.c > index c01f177..d17a694 100644 > --- a/mm/khugepaged.c > +++ b/mm/khugepaged.c > @@ -745,14 +745,13 @@ khugepaged_alloc_page(struct page **hpage, gfp_t gfp, int node) > { > VM_BUG_ON_PAGE(*hpage, *hpage); > > - *hpage = __alloc_pages_node(node, gfp, HPAGE_PMD_ORDER); > + *hpage = alloc_transhuge_page_node(node, gfp); > if (unlikely(!*hpage)) { > count_vm_event(THP_COLLAPSE_ALLOC_FAILED); > *hpage = ERR_PTR(-ENOMEM); > return NULL; > } > > - prep_transhuge_page(*hpage); > count_vm_event(THP_COLLAPSE_ALLOC); > return *hpage; > } > @@ -764,13 +763,7 @@ static int khugepaged_find_target_node(void) > > static inline struct page *alloc_khugepaged_hugepage(void) > { > - struct page *page; > - > - page = alloc_pages(alloc_hugepage_khugepaged_gfpmask(), > - HPAGE_PMD_ORDER); > - if (page) > - prep_transhuge_page(page); > - return page; > + return alloc_transhuge_page(alloc_hugepage_khugepaged_gfpmask()); > } > > static struct page *khugepaged_alloc_hugepage(bool *wait) > diff --git a/mm/mempolicy.c b/mm/mempolicy.c > index a2af6d5..aa24285 100644 > --- a/mm/mempolicy.c > +++ b/mm/mempolicy.c > @@ -949,12 +949,10 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x > else if (thp_migration_supported() && PageTransHuge(page)) { > struct page *thp; > > - thp = alloc_pages_node(node, > - (GFP_TRANSHUGE | __GFP_THISNODE), > - HPAGE_PMD_ORDER); > + thp = alloc_transhuge_page_node(node, > + (GFP_TRANSHUGE | __GFP_THISNODE)); > if (!thp) > return NULL; > - prep_transhuge_page(thp); > return thp; > } else > return __alloc_pages_node(node, GFP_HIGHUSER_MOVABLE | > @@ -1125,11 +1123,9 @@ static struct page *new_page(struct page *page, unsigned long start, int **x) > } else if (thp_migration_supported() && PageTransHuge(page)) { > struct page *thp; > > - thp = alloc_hugepage_vma(GFP_TRANSHUGE, vma, address, > - HPAGE_PMD_ORDER); > + thp = alloc_transhuge_page_vma(GFP_TRANSHUGE, vma, address); > if (!thp) > return NULL; > - prep_transhuge_page(thp); > return thp; > } > /* > diff --git a/mm/migrate.c b/mm/migrate.c > index e00814c..7f0486f 100644 > --- a/mm/migrate.c > +++ b/mm/migrate.c > @@ -1472,12 +1472,10 @@ static struct page *new_page_node(struct page *p, unsigned long private, > else if (thp_migration_supported() && PageTransHuge(p)) { > struct page *thp; > > - thp = alloc_pages_node(pm->node, > - (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM, > - HPAGE_PMD_ORDER); > + thp = alloc_transhuge_page_node(pm->node, > + (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM); > if (!thp) > return NULL; > - prep_transhuge_page(thp); > return thp; > } else > return __alloc_pages_node(pm->node, > @@ -2017,12 +2015,10 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, > if (numamigrate_update_ratelimit(pgdat, HPAGE_PMD_NR)) > goto out_dropref; > > - new_page = alloc_pages_node(node, > - (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE), > - HPAGE_PMD_ORDER); > + new_page = alloc_transhuge_page_node(node, > + (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE)); > if (!new_page) > goto out_fail; > - prep_transhuge_page(new_page); > > isolated = numamigrate_isolate_page(pgdat, page); > if (!isolated) { > diff --git a/mm/shmem.c b/mm/shmem.c > index 07a1d22..52468f7 100644 > --- a/mm/shmem.c > +++ b/mm/shmem.c > @@ -1444,11 +1444,9 @@ static struct page *shmem_alloc_hugepage(gfp_t gfp, > rcu_read_unlock(); > > shmem_pseudo_vma_init(&pvma, info, hindex); > - page = alloc_pages_vma(gfp | __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN, > - HPAGE_PMD_ORDER, &pvma, 0, numa_node_id(), true); > + gfp |= __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN; > + page = alloc_transhuge_page_vma(gfp, &pvma, 0); > shmem_pseudo_vma_destroy(&pvma); > - if (page) > - prep_transhuge_page(page); > return page; > } > > -- > 2.7.4 > > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majordomo@kvack.org. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: email@kvack.org -- Michal Hocko SUSE Labs From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935072AbdJQKWH (ORCPT ); Tue, 17 Oct 2017 06:22:07 -0400 Received: from mx2.suse.de ([195.135.220.15]:48150 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755288AbdJQKWF (ORCPT ); Tue, 17 Oct 2017 06:22:05 -0400 Date: Tue, 17 Oct 2017 12:22:03 +0200 From: Michal Hocko To: changbin.du@intel.com Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: Re: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Message-ID: <20171017102203.u2v3p2ivuogu4rk6@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-3-git-send-email-changbin.du@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1508145557-9944-3-git-send-email-changbin.du@intel.com> User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon 16-10-17 17:19:17, changbin.du@intel.com wrote: > From: Changbin Du > > The current name free_{huge,transhuge}_page are paired with > alloc_{huge,transhuge}_page functions, but the actual page free > function is still free_page() which will indirectly call > free_{huge,transhuge}_page. So this patch removes this confusion > by renaming all the compound page dtors. Is this code churn really worth it? > Signed-off-by: Changbin Du > --- > Documentation/vm/hugetlbfs_reserv.txt | 4 ++-- > include/linux/huge_mm.h | 2 +- > include/linux/hugetlb.h | 2 +- > include/linux/mm.h | 8 ++++---- > mm/huge_memory.c | 4 ++-- > mm/hugetlb.c | 14 +++++++------- > mm/page_alloc.c | 10 +++++----- > mm/swap.c | 2 +- > mm/userfaultfd.c | 2 +- > 9 files changed, 24 insertions(+), 24 deletions(-) > > diff --git a/Documentation/vm/hugetlbfs_reserv.txt b/Documentation/vm/hugetlbfs_reserv.txt > index 9aca09a..b3ffa3e 100644 > --- a/Documentation/vm/hugetlbfs_reserv.txt > +++ b/Documentation/vm/hugetlbfs_reserv.txt > @@ -238,7 +238,7 @@ to the global reservation count (resv_huge_pages). > > Freeing Huge Pages > ------------------ > -Huge page freeing is performed by the routine free_huge_page(). This routine > +Huge page freeing is performed by the routine huge_page_dtor(). This routine > is the destructor for hugetlbfs compound pages. As a result, it is only > passed a pointer to the page struct. When a huge page is freed, reservation > accounting may need to be performed. This would be the case if the page was > @@ -468,7 +468,7 @@ However, there are several instances where errors are encountered after a huge > page is allocated but before it is instantiated. In this case, the page > allocation has consumed the reservation and made the appropriate subpool, > reservation map and global count adjustments. If the page is freed at this > -time (before instantiation and clearing of PagePrivate), then free_huge_page > +time (before instantiation and clearing of PagePrivate), then huge_page_dtor > will increment the global reservation count. However, the reservation map > indicates the reservation was consumed. This resulting inconsistent state > will cause the 'leak' of a reserved huge page. The global reserve count will > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > index 1dd2c33..40ae3058 100644 > --- a/include/linux/huge_mm.h > +++ b/include/linux/huge_mm.h > @@ -130,7 +130,7 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > unsigned long addr, unsigned long len, unsigned long pgoff, > unsigned long flags); > > -extern void free_transhuge_page(struct page *page); > +extern void transhuge_page_dtor(struct page *page); > > struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > struct vm_area_struct *vma, unsigned long addr); > diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h > index 8bbbd37..24492c5 100644 > --- a/include/linux/hugetlb.h > +++ b/include/linux/hugetlb.h > @@ -118,7 +118,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end, > long freed); > bool isolate_huge_page(struct page *page, struct list_head *list); > void putback_active_hugepage(struct page *page); > -void free_huge_page(struct page *page); > +void huge_page_dtor(struct page *page); > void hugetlb_fix_reserve_counts(struct inode *inode); > extern struct mutex *hugetlb_fault_mutex_table; > u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm, > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 065d99d..adfa906 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -616,7 +616,7 @@ void split_page(struct page *page, unsigned int order); > * prototype for that function and accessor functions. > * These are _only_ valid on the head of a compound page. > */ > -typedef void compound_page_dtor(struct page *); > +typedef void compound_page_dtor_t(struct page *); > > /* Keep the enum in sync with compound_page_dtors array in mm/page_alloc.c */ > enum compound_dtor_id { > @@ -630,7 +630,7 @@ enum compound_dtor_id { > #endif > NR_COMPOUND_DTORS, > }; > -extern compound_page_dtor * const compound_page_dtors[]; > +extern compound_page_dtor_t * const compound_page_dtors[]; > > static inline void set_compound_page_dtor(struct page *page, > enum compound_dtor_id compound_dtor) > @@ -639,7 +639,7 @@ static inline void set_compound_page_dtor(struct page *page, > page[1].compound_dtor = compound_dtor; > } > > -static inline compound_page_dtor *get_compound_page_dtor(struct page *page) > +static inline compound_page_dtor_t *get_compound_page_dtor(struct page *page) > { > VM_BUG_ON_PAGE(page[1].compound_dtor >= NR_COMPOUND_DTORS, page); > return compound_page_dtors[page[1].compound_dtor]; > @@ -657,7 +657,7 @@ static inline void set_compound_order(struct page *page, unsigned int order) > page[1].compound_order = order; > } > > -void free_compound_page(struct page *page); > +void compound_page_dtor(struct page *page); > > #ifdef CONFIG_MMU > /* > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index e267488..a01125b 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -2717,7 +2717,7 @@ fail: if (mapping) > return ret; > } > > -void free_transhuge_page(struct page *page) > +void transhuge_page_dtor(struct page *page) > { > struct pglist_data *pgdata = NODE_DATA(page_to_nid(page)); > unsigned long flags; > @@ -2728,7 +2728,7 @@ void free_transhuge_page(struct page *page) > list_del(page_deferred_list(page)); > } > spin_unlock_irqrestore(&pgdata->split_queue_lock, flags); > - free_compound_page(page); > + compound_page_dtor(page); > } > > void deferred_split_huge_page(struct page *page) > diff --git a/mm/hugetlb.c b/mm/hugetlb.c > index 424b0ef..1af2c4e7 100644 > --- a/mm/hugetlb.c > +++ b/mm/hugetlb.c > @@ -1250,7 +1250,7 @@ static void clear_page_huge_active(struct page *page) > ClearPagePrivate(&page[1]); > } > > -void free_huge_page(struct page *page) > +void huge_page_dtor(struct page *page) > { > /* > * Can't pass hstate in here because it is called from the > @@ -1363,7 +1363,7 @@ int PageHeadHuge(struct page *page_head) > if (!PageHead(page_head)) > return 0; > > - return get_compound_page_dtor(page_head) == free_huge_page; > + return get_compound_page_dtor(page_head) == huge_page_dtor; > } > > pgoff_t __basepage_index(struct page *page) > @@ -1932,11 +1932,11 @@ static long vma_add_reservation(struct hstate *h, > * specific error paths, a huge page was allocated (via alloc_huge_page) > * and is about to be freed. If a reservation for the page existed, > * alloc_huge_page would have consumed the reservation and set PagePrivate > - * in the newly allocated page. When the page is freed via free_huge_page, > + * in the newly allocated page. When the page is freed via huge_page_dtor, > * the global reservation count will be incremented if PagePrivate is set. > - * However, free_huge_page can not adjust the reserve map. Adjust the > + * However, huge_page_dtor can not adjust the reserve map. Adjust the > * reserve map here to be consistent with global reserve count adjustments > - * to be made by free_huge_page. > + * to be made by huge_page_dtor. > */ > static void restore_reserve_on_error(struct hstate *h, > struct vm_area_struct *vma, unsigned long address, > @@ -1950,7 +1950,7 @@ static void restore_reserve_on_error(struct hstate *h, > * Rare out of memory condition in reserve map > * manipulation. Clear PagePrivate so that > * global reserve count will not be incremented > - * by free_huge_page. This will make it appear > + * by huge_page_dtor. This will make it appear > * as though the reservation for this page was > * consumed. This may prevent the task from > * faulting in the page at a later time. This > @@ -2304,7 +2304,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, > while (count > persistent_huge_pages(h)) { > /* > * If this allocation races such that we no longer need the > - * page, free_huge_page will handle it by freeing the page > + * page, huge_page_dtor will handle it by freeing the page > * and reducing the surplus. > */ > spin_unlock(&hugetlb_lock); > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > index 77e4d3c..b31205c 100644 > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -248,14 +248,14 @@ char * const migratetype_names[MIGRATE_TYPES] = { > #endif > }; > > -compound_page_dtor * const compound_page_dtors[] = { > +compound_page_dtor_t * const compound_page_dtors[] = { > NULL, > - free_compound_page, > + compound_page_dtor, > #ifdef CONFIG_HUGETLB_PAGE > - free_huge_page, > + huge_page_dtor, > #endif > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - free_transhuge_page, > + transhuge_page_dtor, > #endif > }; > > @@ -586,7 +586,7 @@ static void bad_page(struct page *page, const char *reason, > * This usage means that zero-order pages may not be compound. > */ > > -void free_compound_page(struct page *page) > +void compound_page_dtor(struct page *page) > { > __free_pages_ok(page, compound_order(page)); > } > diff --git a/mm/swap.c b/mm/swap.c > index a77d68f..8f98caf 100644 > --- a/mm/swap.c > +++ b/mm/swap.c > @@ -81,7 +81,7 @@ static void __put_single_page(struct page *page) > > static void __put_compound_page(struct page *page) > { > - compound_page_dtor *dtor; > + compound_page_dtor_t *dtor; > > /* > * __page_cache_release() is supposed to be called for thp, not for > diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c > index 8119270..91d9045 100644 > --- a/mm/userfaultfd.c > +++ b/mm/userfaultfd.c > @@ -323,7 +323,7 @@ static __always_inline ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm, > * map of a private mapping, the map was modified to indicate > * the reservation was consumed when the page was allocated. > * We clear the PagePrivate flag now so that the global > - * reserve count will not be incremented in free_huge_page. > + * reserve count will not be incremented in huge_page_dtor. > * The reservation map will still indicate the reservation > * was consumed and possibly prevent later page allocation. > * This is better than leaking a global reservation. If no > -- > 2.7.4 > > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majordomo@kvack.org. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: email@kvack.org -- Michal Hocko SUSE Labs From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935090AbdJQKW2 (ORCPT ); Tue, 17 Oct 2017 06:22:28 -0400 Received: from mx2.suse.de ([195.135.220.15]:48192 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753928AbdJQKW1 (ORCPT ); Tue, 17 Oct 2017 06:22:27 -0400 Date: Tue, 17 Oct 2017 12:22:24 +0200 From: Michal Hocko To: changbin.du@intel.com Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, "Kirill A. Shutemov" Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171017102224.irddxjgigcv7yxlg@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue 17-10-17 12:20:52, Michal Hocko wrote: > [CC Kirill] now for real > On Mon 16-10-17 17:19:16, changbin.du@intel.com wrote: > > From: Changbin Du > > > > This patch introduced 4 new interfaces to allocate a prepared > > transparent huge page. > > - alloc_transhuge_page_vma > > - alloc_transhuge_page_nodemask > > - alloc_transhuge_page_node > > - alloc_transhuge_page > > > > The aim is to remove duplicated code and simplify transparent > > huge page allocation. These are similar to alloc_hugepage_xxx > > which are for hugetlbfs pages. This patch does below changes: > > - define alloc_transhuge_page_xxx interfaces > > - apply them to all existing code > > - declare prep_transhuge_page as static since no others use it > > - remove alloc_hugepage_vma definition since it no longer has users > > So what exactly is the advantage of the new API? The diffstat doesn't > sound very convincing to me. > > > Signed-off-by: Changbin Du > > --- > > include/linux/gfp.h | 4 ---- > > include/linux/huge_mm.h | 13 ++++++++++++- > > include/linux/migrate.h | 14 +++++--------- > > mm/huge_memory.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- > > mm/khugepaged.c | 11 ++--------- > > mm/mempolicy.c | 10 +++------- > > mm/migrate.c | 12 ++++-------- > > mm/shmem.c | 6 ++---- > > 8 files changed, 71 insertions(+), 49 deletions(-) > > > > diff --git a/include/linux/gfp.h b/include/linux/gfp.h > > index f780718..855c72e 100644 > > --- a/include/linux/gfp.h > > +++ b/include/linux/gfp.h > > @@ -507,15 +507,11 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) > > extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, > > struct vm_area_struct *vma, unsigned long addr, > > int node, bool hugepage); > > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > > - alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) > > #else > > #define alloc_pages(gfp_mask, order) \ > > alloc_pages_node(numa_node_id(), gfp_mask, order) > > #define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ > > alloc_pages(gfp_mask, order) > > -#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ > > - alloc_pages(gfp_mask, order) > > #endif > > #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) > > #define alloc_page_vma(gfp_mask, vma, addr) \ > > diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h > > index 14bc21c..1dd2c33 100644 > > --- a/include/linux/huge_mm.h > > +++ b/include/linux/huge_mm.h > > @@ -130,9 +130,20 @@ extern unsigned long thp_get_unmapped_area(struct file *filp, > > unsigned long addr, unsigned long len, unsigned long pgoff, > > unsigned long flags); > > > > -extern void prep_transhuge_page(struct page *page); > > extern void free_transhuge_page(struct page *page); > > > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > > + struct vm_area_struct *vma, unsigned long addr); > > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > > + int preferred_nid, nodemask_t *nmask); > > + > > +static inline struct page *alloc_transhuge_page_node(int nid, gfp_t gfp_mask) > > +{ > > + return alloc_transhuge_page_nodemask(gfp_mask, nid, NULL); > > +} > > + > > +struct page *alloc_transhuge_page(gfp_t gfp_mask); > > + > > bool can_split_huge_page(struct page *page, int *pextra_pins); > > int split_huge_page_to_list(struct page *page, struct list_head *list); > > static inline int split_huge_page(struct page *page) > > diff --git a/include/linux/migrate.h b/include/linux/migrate.h > > index 643c7ae..70a00f3 100644 > > --- a/include/linux/migrate.h > > +++ b/include/linux/migrate.h > > @@ -42,19 +42,15 @@ static inline struct page *new_page_nodemask(struct page *page, > > return alloc_huge_page_nodemask(page_hstate(compound_head(page)), > > preferred_nid, nodemask); > > > > - if (thp_migration_supported() && PageTransHuge(page)) { > > - order = HPAGE_PMD_ORDER; > > - gfp_mask |= GFP_TRANSHUGE; > > - } > > - > > if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) > > gfp_mask |= __GFP_HIGHMEM; > > > > - new_page = __alloc_pages_nodemask(gfp_mask, order, > > + if (thp_migration_supported() && PageTransHuge(page)) > > + return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, > > + preferred_nid, nodemask); > > + else > > + return __alloc_pages_nodemask(gfp_mask, order, > > preferred_nid, nodemask); > > - > > - if (new_page && PageTransHuge(page)) > > - prep_transhuge_page(new_page); > > > > return new_page; > > } > > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > > index 269b5df..e267488 100644 > > --- a/mm/huge_memory.c > > +++ b/mm/huge_memory.c > > @@ -490,7 +490,7 @@ static inline struct list_head *page_deferred_list(struct page *page) > > return (struct list_head *)&page[2].mapping; > > } > > > > -void prep_transhuge_page(struct page *page) > > +static void prep_transhuge_page(struct page *page) > > { > > /* > > * we use page->mapping and page->indexlru in second tail page > > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > > } > > > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > > + struct vm_area_struct *vma, unsigned long addr) > > +{ > > + struct page *page; > > + > > + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > > + vma, addr, numa_node_id(), true); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > > + int preferred_nid, nodemask_t *nmask) > > +{ > > + struct page *page; > > + > > + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > > + preferred_nid, nmask); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > > +{ > > + struct page *page; > > + > > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); > > + > > + page = alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); > > + if (unlikely(!page)) > > + return NULL; > > + prep_transhuge_page(page); > > + return page; > > +} > > + > > unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, > > loff_t off, unsigned long flags, unsigned long size) > > { > > @@ -719,12 +758,11 @@ int do_huge_pmd_anonymous_page(struct vm_fault *vmf) > > return ret; > > } > > gfp = alloc_hugepage_direct_gfpmask(vma); > > - page = alloc_hugepage_vma(gfp, vma, haddr, HPAGE_PMD_ORDER); > > + page = alloc_transhuge_page_vma(gfp, vma, haddr); > > if (unlikely(!page)) { > > count_vm_event(THP_FAULT_FALLBACK); > > return VM_FAULT_FALLBACK; > > } > > - prep_transhuge_page(page); > > return __do_huge_pmd_anonymous_page(vmf, page, gfp); > > } > > > > @@ -1288,13 +1326,11 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) > > if (transparent_hugepage_enabled(vma) && > > !transparent_hugepage_debug_cow()) { > > huge_gfp = alloc_hugepage_direct_gfpmask(vma); > > - new_page = alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDER); > > + new_page = alloc_transhuge_page_vma(huge_gfp, vma, haddr); > > } else > > new_page = NULL; > > > > - if (likely(new_page)) { > > - prep_transhuge_page(new_page); > > - } else { > > + if (unlikely(!new_page)) { > > if (!page) { > > split_huge_pmd(vma, vmf->pmd, vmf->address); > > ret |= VM_FAULT_FALLBACK; > > diff --git a/mm/khugepaged.c b/mm/khugepaged.c > > index c01f177..d17a694 100644 > > --- a/mm/khugepaged.c > > +++ b/mm/khugepaged.c > > @@ -745,14 +745,13 @@ khugepaged_alloc_page(struct page **hpage, gfp_t gfp, int node) > > { > > VM_BUG_ON_PAGE(*hpage, *hpage); > > > > - *hpage = __alloc_pages_node(node, gfp, HPAGE_PMD_ORDER); > > + *hpage = alloc_transhuge_page_node(node, gfp); > > if (unlikely(!*hpage)) { > > count_vm_event(THP_COLLAPSE_ALLOC_FAILED); > > *hpage = ERR_PTR(-ENOMEM); > > return NULL; > > } > > > > - prep_transhuge_page(*hpage); > > count_vm_event(THP_COLLAPSE_ALLOC); > > return *hpage; > > } > > @@ -764,13 +763,7 @@ static int khugepaged_find_target_node(void) > > > > static inline struct page *alloc_khugepaged_hugepage(void) > > { > > - struct page *page; > > - > > - page = alloc_pages(alloc_hugepage_khugepaged_gfpmask(), > > - HPAGE_PMD_ORDER); > > - if (page) > > - prep_transhuge_page(page); > > - return page; > > + return alloc_transhuge_page(alloc_hugepage_khugepaged_gfpmask()); > > } > > > > static struct page *khugepaged_alloc_hugepage(bool *wait) > > diff --git a/mm/mempolicy.c b/mm/mempolicy.c > > index a2af6d5..aa24285 100644 > > --- a/mm/mempolicy.c > > +++ b/mm/mempolicy.c > > @@ -949,12 +949,10 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x > > else if (thp_migration_supported() && PageTransHuge(page)) { > > struct page *thp; > > > > - thp = alloc_pages_node(node, > > - (GFP_TRANSHUGE | __GFP_THISNODE), > > - HPAGE_PMD_ORDER); > > + thp = alloc_transhuge_page_node(node, > > + (GFP_TRANSHUGE | __GFP_THISNODE)); > > if (!thp) > > return NULL; > > - prep_transhuge_page(thp); > > return thp; > > } else > > return __alloc_pages_node(node, GFP_HIGHUSER_MOVABLE | > > @@ -1125,11 +1123,9 @@ static struct page *new_page(struct page *page, unsigned long start, int **x) > > } else if (thp_migration_supported() && PageTransHuge(page)) { > > struct page *thp; > > > > - thp = alloc_hugepage_vma(GFP_TRANSHUGE, vma, address, > > - HPAGE_PMD_ORDER); > > + thp = alloc_transhuge_page_vma(GFP_TRANSHUGE, vma, address); > > if (!thp) > > return NULL; > > - prep_transhuge_page(thp); > > return thp; > > } > > /* > > diff --git a/mm/migrate.c b/mm/migrate.c > > index e00814c..7f0486f 100644 > > --- a/mm/migrate.c > > +++ b/mm/migrate.c > > @@ -1472,12 +1472,10 @@ static struct page *new_page_node(struct page *p, unsigned long private, > > else if (thp_migration_supported() && PageTransHuge(p)) { > > struct page *thp; > > > > - thp = alloc_pages_node(pm->node, > > - (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM, > > - HPAGE_PMD_ORDER); > > + thp = alloc_transhuge_page_node(pm->node, > > + (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM); > > if (!thp) > > return NULL; > > - prep_transhuge_page(thp); > > return thp; > > } else > > return __alloc_pages_node(pm->node, > > @@ -2017,12 +2015,10 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, > > if (numamigrate_update_ratelimit(pgdat, HPAGE_PMD_NR)) > > goto out_dropref; > > > > - new_page = alloc_pages_node(node, > > - (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE), > > - HPAGE_PMD_ORDER); > > + new_page = alloc_transhuge_page_node(node, > > + (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE)); > > if (!new_page) > > goto out_fail; > > - prep_transhuge_page(new_page); > > > > isolated = numamigrate_isolate_page(pgdat, page); > > if (!isolated) { > > diff --git a/mm/shmem.c b/mm/shmem.c > > index 07a1d22..52468f7 100644 > > --- a/mm/shmem.c > > +++ b/mm/shmem.c > > @@ -1444,11 +1444,9 @@ static struct page *shmem_alloc_hugepage(gfp_t gfp, > > rcu_read_unlock(); > > > > shmem_pseudo_vma_init(&pvma, info, hindex); > > - page = alloc_pages_vma(gfp | __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN, > > - HPAGE_PMD_ORDER, &pvma, 0, numa_node_id(), true); > > + gfp |= __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN; > > + page = alloc_transhuge_page_vma(gfp, &pvma, 0); > > shmem_pseudo_vma_destroy(&pvma); > > - if (page) > > - prep_transhuge_page(page); > > return page; > > } > > > > -- > > 2.7.4 > > > > -- > > To unsubscribe, send a message with 'unsubscribe linux-mm' in > > the body to majordomo@kvack.org. For more info on Linux MM, > > see: http://www.linux-mm.org/ . > > Don't email: email@kvack.org > > -- > Michal Hocko > SUSE Labs -- Michal Hocko SUSE Labs From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932540AbdJQLMv (ORCPT ); Tue, 17 Oct 2017 07:12:51 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:43451 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932307AbdJQLMt (ORCPT ); Tue, 17 Oct 2017 07:12:49 -0400 X-Google-Smtp-Source: AOwi7QBZFvWx56fDA60Ybv+C9oQ7Oh7r+nDpNIWnls8FAcOl8fO3v+5eAS/560Bo8cezr2YHOJmKjg== Date: Tue, 17 Oct 2017 14:12:46 +0300 From: "Kirill A. Shutemov" To: changbin.du@intel.com Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171017111246.7rhmy7klggxjozom@node.shutemov.name> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Oct 16, 2017 at 05:19:16PM +0800, changbin.du@intel.com wrote: > @@ -501,6 +501,45 @@ void prep_transhuge_page(struct page *page) > set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR); > } > > +struct page *alloc_transhuge_page_vma(gfp_t gfp_mask, > + struct vm_area_struct *vma, unsigned long addr) > +{ > + struct page *page; > + > + page = alloc_pages_vma(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + vma, addr, numa_node_id(), true); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > +struct page *alloc_transhuge_page_nodemask(gfp_t gfp_mask, > + int preferred_nid, nodemask_t *nmask) > +{ > + struct page *page; > + > + page = __alloc_pages_nodemask(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER, > + preferred_nid, nmask); > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > +struct page *alloc_transhuge_page(gfp_t gfp_mask) > +{ > + struct page *page; > + > + VM_BUG_ON(!(gfp_mask & __GFP_COMP)); Why do you check for __GFP_COMP only in this helper? > + page = alloc_pages(gfp_mask | __GFP_COMP, HPAGE_PMD_ORDER); And still apply __GFP_COMP anyway? > + if (unlikely(!page)) > + return NULL; > + prep_transhuge_page(page); > + return page; > +} > + > unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len, > loff_t off, unsigned long flags, unsigned long size) > { -- Kirill A. Shutemov From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756917AbdJQLWT (ORCPT ); Tue, 17 Oct 2017 07:22:19 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:44415 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756405AbdJQLWQ (ORCPT ); Tue, 17 Oct 2017 07:22:16 -0400 X-Google-Smtp-Source: AOwi7QCJeAQDpBLVlerMYJqTgMOHU+BNUbQlM0g4YozxorlNTjBq64mgwZGnVCMAWv/nAt+eIedoAQ== Date: Tue, 17 Oct 2017 14:22:14 +0300 From: "Kirill A. Shutemov" To: Michal Hocko Cc: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: Re: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Message-ID: <20171017112214.n5emzjzstmbktn6m@node.shutemov.name> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-3-git-send-email-changbin.du@intel.com> <20171017102203.u2v3p2ivuogu4rk6@dhcp22.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171017102203.u2v3p2ivuogu4rk6@dhcp22.suse.cz> User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Oct 17, 2017 at 12:22:03PM +0200, Michal Hocko wrote: > On Mon 16-10-17 17:19:17, changbin.du@intel.com wrote: > > From: Changbin Du > > > > The current name free_{huge,transhuge}_page are paired with > > alloc_{huge,transhuge}_page functions, but the actual page free > > function is still free_page() which will indirectly call > > free_{huge,transhuge}_page. So this patch removes this confusion > > by renaming all the compound page dtors. > > Is this code churn really worth it? Getting naming straight is kinda nit. :) But I don't feel strong either way. -- Kirill A. Shutemov From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935463AbdJQMA0 (ORCPT ); Tue, 17 Oct 2017 08:00:26 -0400 Received: from mx2.suse.de ([195.135.220.15]:56713 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932983AbdJQMAY (ORCPT ); Tue, 17 Oct 2017 08:00:24 -0400 Date: Tue, 17 Oct 2017 14:00:22 +0200 From: Michal Hocko To: "Kirill A. Shutemov" Cc: changbin.du@intel.com, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: Re: [PATCH 2/2] mm: rename page dtor functions to {compound,huge,transhuge}_page__dtor Message-ID: <20171017120022.m4gblhcfs7xf7zld@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-3-git-send-email-changbin.du@intel.com> <20171017102203.u2v3p2ivuogu4rk6@dhcp22.suse.cz> <20171017112214.n5emzjzstmbktn6m@node.shutemov.name> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171017112214.n5emzjzstmbktn6m@node.shutemov.name> User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue 17-10-17 14:22:14, Kirill A. Shutemov wrote: > On Tue, Oct 17, 2017 at 12:22:03PM +0200, Michal Hocko wrote: > > On Mon 16-10-17 17:19:17, changbin.du@intel.com wrote: > > > From: Changbin Du > > > > > > The current name free_{huge,transhuge}_page are paired with > > > alloc_{huge,transhuge}_page functions, but the actual page free > > > function is still free_page() which will indirectly call > > > free_{huge,transhuge}_page. So this patch removes this confusion > > > by renaming all the compound page dtors. > > > > Is this code churn really worth it? > > Getting naming straight is kinda nit. :) yes > But I don't feel strong either way. Me neither, I am just trying to understand why the patch has been created? Is it a preparation for some other changes? If it was removing some code it would be much more clear but it actually adds twice as much as it removes so it doesn't save anything there. It makes the API more explicit which might be good but is it worth that? -- Michal Hocko SUSE Labs From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1764163AbdJQX2T (ORCPT ); Tue, 17 Oct 2017 19:28:19 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:60912 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755780AbdJQX2S (ORCPT ); Tue, 17 Oct 2017 19:28:18 -0400 Date: Tue, 17 Oct 2017 16:28:16 -0700 From: Andrew Morton To: changbin.du@intel.com Cc: corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: Re: [PATCH 0/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-Id: <20171017162816.c5751bda5d51d3bf560b8503@linux-foundation.org> In-Reply-To: <1508145557-9944-1-git-send-email-changbin.du@intel.com> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> X-Mailer: Sylpheed 3.4.1 (GTK+ 2.24.23; x86_64-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 16 Oct 2017 17:19:15 +0800 changbin.du@intel.com wrote: > The first one introduce new interfaces, the second one kills naming confusion. > The aim is to remove duplicated code and simplify transparent huge page > allocation. These introduce various allnoconfig build errors. From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751686AbdJRPz2 (ORCPT ); Wed, 18 Oct 2017 11:55:28 -0400 Received: from mga06.intel.com ([134.134.136.31]:47041 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751462AbdJRPz0 (ORCPT ); Wed, 18 Oct 2017 11:55:26 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,397,1503385200"; d="gz'50?scan'50,208,50";a="1232253011" Date: Wed, 18 Oct 2017 23:54:55 +0800 From: kbuild test robot To: changbin.du@intel.com Cc: kbuild-all@01.org, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Changbin Du Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <201710182319.H5PtDUyn%fengguang.wu@intel.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="/04w6evG8XlLl3ft" Content-Disposition: inline In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --/04w6evG8XlLl3ft Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Changbin, [auto build test ERROR on mmotm/master] [also build test ERROR on v4.14-rc5 next-20171017] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/changbin-du-intel-com/mm-thp-introduce-dedicated-transparent-huge-page-allocation-interfaces/20171018-230128 base: git://git.cmpxchg.org/linux-mmotm.git master config: i386-randconfig-x003-201742 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from mm/shmem.c:70:0: include/linux/migrate.h: In function 'new_page_nodemask': include/linux/migrate.h:49:10: error: implicit declaration of function 'alloc_transhuge_page_nodemask' [-Werror=implicit-function-declaration] return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/migrate.h:49:10: warning: return makes pointer from integer without a cast [-Wint-conversion] return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ preferred_nid, nodemask); ~~~~~~~~~~~~~~~~~~~~~~~~ mm/shmem.c: In function 'shmem_alloc_hugepage': >> mm/shmem.c:1448:9: error: implicit declaration of function 'alloc_transhuge_page_vma' [-Werror=implicit-function-declaration] page = alloc_transhuge_page_vma(gfp, &pvma, 0); ^~~~~~~~~~~~~~~~~~~~~~~~ >> mm/shmem.c:1448:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion] page = alloc_transhuge_page_vma(gfp, &pvma, 0); ^ cc1: some warnings being treated as errors vim +/alloc_transhuge_page_vma +1448 mm/shmem.c 1423 1424 static struct page *shmem_alloc_hugepage(gfp_t gfp, 1425 struct shmem_inode_info *info, pgoff_t index) 1426 { 1427 struct vm_area_struct pvma; 1428 struct inode *inode = &info->vfs_inode; 1429 struct address_space *mapping = inode->i_mapping; 1430 pgoff_t idx, hindex; 1431 void __rcu **results; 1432 struct page *page; 1433 1434 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE)) 1435 return NULL; 1436 1437 hindex = round_down(index, HPAGE_PMD_NR); 1438 rcu_read_lock(); 1439 if (radix_tree_gang_lookup_slot(&mapping->page_tree, &results, &idx, 1440 hindex, 1) && idx < hindex + HPAGE_PMD_NR) { 1441 rcu_read_unlock(); 1442 return NULL; 1443 } 1444 rcu_read_unlock(); 1445 1446 shmem_pseudo_vma_init(&pvma, info, hindex); 1447 gfp |= __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN; > 1448 page = alloc_transhuge_page_vma(gfp, &pvma, 0); 1449 shmem_pseudo_vma_destroy(&pvma); 1450 return page; 1451 } 1452 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --/04w6evG8XlLl3ft Content-Type: application/gzip Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 H4sICL5z51kAAy5jb25maWcAlDzLcuO2svt8hWpyF+cskvFrHKdueQGBoIgjguAAoB7esByP ZuKKx5pryyfJ399ugBQBEFSSWUyZ3Y13vxvQ9999PyNvh/3X+8Pjw/3T05+zL7vn3cv9Yfdp 9vnxafe/s0zOKmlmLOPmRyAuH5/f/nj/eHlzPbv68fzqx7MfXh4uf/j69Xy23L08755mdP/8 +fHLG3TxuH/+7ntoQmWV80V7fTXnZvb4OnveH2avu8N3HXxzc91eXtz+6X0PH7zSRjXUcFm1 GaMyY2pAysbUjWlzqQQxt+92T58vL37Aqb3rKYiiBbTL3eftu/uXh1/f/3Fz/f7BzvLVLqT9 tPvsvo/tSkmXGatb3dS1VGYYUhtCl0YRysY4IZrhw44sBKlbVWUtrFy3gle3N6fwZHN7fp0m oFLUxPxlPwFZ0F3FWNZmgrRICqswbJirxemFRZesWphiwC1YxRSnLdcE8WPEvFmMgcWa8UVh 4u0g27YgK9bWtM0zOmDVWjPRbmixIFnWknIhFTeFGPdLScnnCiYPh1qSbdR/QXRL66ZVgNuk cIQWrC15BYfH77wNsJPSzDR1WzNl+yCKkWiHehQTc/jKudKmpUVTLSfoarJgaTI3Iz5nqiKW tWupNZ+XLCLRja4ZHOsEek0q0xYNjFILOMAC5pyisJtHSktpyvloDMvGupW14QK2JQOhgz3i 1WKKMmNw6HZ5pARJCUQXRLktyd22Xeip5k2t5Jx56JxvWkZUuYXvVjDv3OuFIbBu4MoVK/Xt ZQ8/ijScpgbRf//0+Mv7r/tPb0+71/f/01REMOQCRjR7/2Mk21x9bNdSeccxb3iZweJZyzZu PB0ItimAGXBbcgn/tYZobGx128JqyyfUZ2/fANL3qOSSVS0sR4va12bctKxawYbgzAU3t5cX PZIqOGUrwRxO+t27QXN2sNYwnVKgcASkXDGlgZOwXQLcksbIiN+XwH2sbBd3vE5j5oC5SKPK O18V+JjN3VSLifHLuytAHNfqzcpfaoy3cztFgDM8hd/cJXYymOu4x6tEE+BE0pQghlIbZLvb d/963j/v/u0dn16T9Fr0Vq94TRO9gsCDTIiPDWs8kfah2JiackA69gHpkWrbEgN2ytPieUGq zNcfjWagST0JbcC+RwdkpdYicCwQ9Yg8DQWdY/yhHdAoxnqZAQGcvb798vrn62H3dZCZo6UB +bQaImGEAKULufYkCiCZFARMYgDTXKSIQOmCKoR1bcedC82RchIxGsefFTggCs7G6kNipPL5 xxveas7EeSMJuDEUlK9TNoH21TVRmnWTO3brD2/7zXWiZ4qujJYN9O1OJpOxXvdJMmI8wfYx KzC9GVrekqBB29IycUBWia5GjHE039gfqPLK6JNI1J8kozDQaTLwhFqS/adJ0gmJpiZzno5l PPP4dffymuI9w+kStDUD5vK6qmRb3KH2FbLydx6AYOO5zHhKdl0r7sTt2MZCk1qgAE8JjJW2 m6eCM3Tuc928N/evv80OMP3Z/fOn2evh/vA6u3942L89Hx6fv0TrsO4LpbKpTMBGyCj2gFLI uc5Q6igDJQJ4M41pV5eeaQRbiN6k9teKQOeg2QaJPbIUm26csB2X3vxGm6FoM9Pj86tBvYja tID2O4RPMOlwVqk5aEfcjw09xCBcWxuAsENYblkOXOFhnB/NFnRuvZLQvwCnvLrwfCW+7IKS EcTu9gAuJfaQg+Ljubk9/2lYM6/MstUkZzHN0U+yeryBGMp5NeD+Zk6AUn7iHNUDEDQVxgjg KbZ52WhPldOFkk3tia71cO1Z+WEZ2CC68I9hXi67tikFZRFubp7BIly1IWZwh3JQEGDP1jwz RVKklPHbTg9a80zHy2tVEOZ0wBzY444Far3DZGzFKUtOo6MAeZwQg34aTOXJniNjMTgOki6P VKCx06MXjC5rCUyC2gVsEkspK3BZwLxQFghwA7q1SlkT8FYAEZBqiHaStLC5jvYYG5ng23Ej OqZ2IX6nYEByDDNArMGaJk9QhfEfshichPWwlcdH9psI6M2ZMc8/Vlnk+wKgd3kHTspGnuSA sb5uSCrT/JhNeI+UHsMutP+WEzCbUdHAeMRkGL2mNFrkEpIKPH9eycwPtpxK4Nm5l2VxDUFV UlbbeNRmOKI2NdX1EqZYEoNz9Pa+Drh3UuFGgwpwmzmyjzcPCFAFGoGRB+E4YgD7rIJT7zCT rrSzrUN/SyDWW5GAtNEAA3yuZdmAAwTLA5FOhQ896RziTsuhhq98/91q7Pi7rQT3bYVnEViZ g3r1o/rpQ8Ah88bfsxwmu4k+QSq97msZ7DFfVKTMPemxu+YDrN+VB9oYTv/E7usiiOcJ96JA kq24Zn1j7yiQKWxU5Q9dU95+bLhaeoTQ95woxUPFbPMzWVJrOEaG3tvYC7VAGLhdiSipUdPz s6veheySnPXu5fP+5ev988Nuxv67ewZ3jIBjRtEhAxfTc0xSY3X5k8kRV8I16U2rb6O6BJ+f vtAlmQciUTbz1FEAGeyYWrA+aA27sDYOHZdWgXGVIpIyw4S1Ne0KXN+cU5u4SsmbkjkvA9+S KqKLiJGXbMNoBJOubQLS7YdVGXXpc7U90RMNQbgcGw+4/zSihihmzkJFAl4shA1LtgU9A4IX J1sGi+fSV2lfHmdjE92gRkCc0MBR9JyneJHlsJUc19ZUYYvIQ0NGQT8SvGLwyNckztlw2El0 22BycRy/jPNtDqqYSSLA0qQbOCgmtfKUfQjU2JBAsKSFlMsIiclm+DZ80cgmEQ5qOCQMorqA ONoOTOeCAjQ83/aWfUygweNwCZHkxFxWz9UX2nXBDQvd9qNnDK7IFhwljG+tcbItoi4VW4CJ qDJXIejOsCV1vCe0TG0E0DmtEOGKNYg6I86Ni3CCb4BZBrS2c4gNPbpncNKNqiAEhe3iviTE 6jBxhgVRGQYM1h81jJrOS0l1khi/V3Kq25esETHn2m0OZDLYV4irXPSSuxRSeMiO71wQREWN JYR4wx3UpUMncJlsJrLr6PC67EufYE1MXjOKerkFhWNG27sA560umwUP/WYPPKUbgMJuGoq0 3XhPo8YoONwqdhkjCjidpiQqHSuMqIHJZZWOPsbE6MSnovwC8zOwQ+AFxYzhtphbEscaucJY JFZrp3IWgZKpMEvGuoIIBqYpOlssAXsb86CQWXeUNaNo3TwfQ2ZNCWoPFTD6Y8pn0aOqsRhr NseFpXGpLyJgG8yQptRc2OomZA9Zb3slZsqAubwFg+VNHiLW8+aN1VDprGEF9gaOZQ3y781X lhn6iV1h6nKEILZUGzBi3WDyazB0eX7CdtpJr7oaJV0mCS2NtIEKKfvsvFpv/hFx7wMlFj/Y DwOGyHiNPIdpGhU3dww0QaOwkNX4ur2H9M68KzNRufrhl/vX3afZb84D/fay//z45JJ/nlKR q25Op9ZlyXoHKQiznMbqLLCz0AVDqQpdRayEeTNGxwxiC194bTii0bG9PRvm18lSYm69lNk0 XAneQuOJ6LzLWB37KecZyRO9YBZAU81hEz82LEjBdfmBuV4kgUExZEgmGLZQ3CTyDHcgH1kI piKzpWVrLlSIW8+DRGcHavXHJM/2aPFxYo0ugMh1OIgGd0DW5Mg09f3L4RFvYczMn992flBC wHGycT6EYJhr8NUOuOTVQOHPOkK1tBGkSqVGYkLGtNxMDtFyqk8NQ7IJhRET1nLNFFikvzEj xTXlm2BUvhnwiR6kzid2RYDWSzcdaAxR/GT3gtB090JnUp9sWmYi3RQRJ3KIi4kZDYFOaWta p8bWTcgrfXBHlCApBMt5eq5YCr2++YsJeRI2OSMUBPERswWhcABsxaGZ7KWDy5l++HWHVwb8 gJ1Ll5espAxSkj08A3OLk0glRzsSmgd1ur5CDOAT9eNuvAjadXn77nm//+aVlGE1f2NCHtVy O/d1Ug+e5169s6nsxQ/Q2zU4ZU2VqBMc73AQIzEeUmIdUaCbZAvUme3GFhCnSdQ6Ihjy7E6F vewfdq+v+5fZAVSYLX593t0f3l58dYa6uLubNPCTSNUa8H5KzghEQ8xlvoeBLQormz0e4/8I L2qr271YFbyenNsSycAoYDTAI8imrrqxjQHPCa8JDTm8Y2Mk6DtNigASuBHKWqfVIpIQMfSf qFAMXJC3Ys4DvrCQYzAa9KoyenlxvplY2OUFeOs8UOWOyYBTjPPuWxuoMpXoodhCqLjiGqKJ RWi6Yc8Jiq7fcQ87od82LKUelitx7H9I8a7E0aQm+zoOF4UiqfRXTxqV2cAFnktpXDZ0kOOr m+vkiOLDCYTRdBInRNoPFtdTHYIjb3gjOP8L9Gm8OIm9SmOXE1Na/jQBv0lpOaoaLYPgV9ho g02YEbHmFcSkNZ0YvUNfZmk0K8lEvwsmM7bYnJ/AtuXE8dAt2NrJTV5xQi/b9IUni5zYMMyv TrRCDT4hyV0AECo/K7hYS+quUbpS87VPUp5P45zSwkwQxq1h18DPIaDLy1xfxWC5ijQyr7ho hA0yc/DEyu3tBx9vpZqaUmg/eQLEYMjclMZg0J1jIAU+Jk2iE5t5EMyQ4A5zUTMTp50zP7em 11wGdzG5FKJpC1bWfpvK3iTVt+eeLuquOmDCJ62sOoKVLEFLEbVNJuktjadku0ZRMNpgUs4w W0YNdx43qo55BDdVjsE29ZYgx6seI6BiSmKVDeuc3TVKVJyYCdKxQRKhWXMug1ea+bp/fjzs X6Io2U94dmxZ0ag8foJYkTpZZxwR0v6adbIza6IxYpk04iVbELptV2JCc8cIr+n59Tw+MKbr nG8ug+q2kSCp81QIx2+W8bHgKUAP7gLIoEc4VRLv5U/MxElesC7gaJ7WrZXEy1BgIycvSgHu KmV2O9z1lRfe29spMs81M7dnf9Az9y9qEa6yJnEWuC62cFZZplrjCjsR3mbvp9GYboFRWlZR ta1jbA7C5bAkcfnbOpvTaFYy2tc3MH/i6zJeIvOUvb+Fl/cadntc+8m2/aQguG9IWCI7zsjh EufQNQ57a63ZcO28IGfoztXe4pwsE/PQhwrAXaejVG6fvVr4GSR3VBD0E5UlOu42ArzPksSR qe20c93cFfAqze26LsHPrY2dnNXaV8Hw7hR7MpR+E87C1nZpGDALvlAkBJ3gyDlob78S5nxW iYler0vR+KWgwQvWKX+gj0RtJtrdt8zU7dXZz9eeGklk36eTsa6iZop6dDG61wL+I4pl4C/T kpHK+hippHUYAsLnifDgiE3fmkWpVozo25+GJne1lGWys7t5k1Zod9rV9hND9HxqHz705dup cBtOgSnFjtVKq9o6ozxEnlgttRisuS75RPnGXV+xMpeOdkBy2jkorEIQlc7AW1WJ8uBM1KS2 rk2aD6wVwOtp7RwiTrwFoJp6IqHjjA/4jStMDK9vr49SBS4sSJVoykhAhFEq/Go1gb3id2wS 3ktnfzPibILMsjmW0tA164nPQxMSa3lwenVbY37Fcm5c4znetvA60Y4XhisteTow6CqP6QO4 a8/PzqZQFx8mUZdhq6C7M0/b3t0iII72C4WXkFOhN9748LSdvRQS1oNRtXH0FYE5FRrt89Bm K2av14fW8Fh2s0WHcB+tKrGtdGIUe+ECRrlwgwy6wV2yWWU6fZ2vz0POI33Qs4zM8FpCmZnx PTbfEnRWp5AGC8HHlNf+993LDPzX+y+7r7vng016EVrz2f4bJvO9xFdXhfMsavdebMii9UsG G1syVgcQrNr20EE7CFDQS2bTcikvV0TEUy8aACXrcLzg6gN8H+tM9m1E4FWuPzrf2CsbTtfr xl3Fi8XtC79659rykh5VnFzxFZ8wdmVJbFL7TxYtpLsW5aZqvX3tPQv1ChX99Y5FMvfl+opP wo0JznWux4GCT6PYqpUrsA88Y/5TwbAnRk/YO0tB4uXNiQHncRtDG2N8dWuBKxhbRrCcVONd kEndYHE2iFcMjj64/dRvA9OYHKTR29UIzYNXTiEyubmuGVksQKfjw52pyZmCKRG6w27SjTYS xEAnE77HGMD1YcW+qcGly+JZxrgE80wUwXAhFPlHTqWcQUD6XEQ0eVkZkJdp1up00xDVh+31 fKoyh21Z2ifyt00wU8gTZODyNPgoCm8hrdHyyqpM5TMGISU1G11D6+Hd9aZwCEQkJ5DVJj8R oddY/5A1sM1k1a/bYvg7KXQ6D2dTB/53//Znlr/s/u9t9/zw5+z14f4peO7TS0yYlrIytJAr fAWo8BLcBHr8sOmIRiFLm76eoo8LsCPv1vo/aIQ7q+F8/n4TzB7axwopjz3VQFYZeNVVllyj Twg49DDtfe1TnUerTfb7Dxb3txcVLSZ9msMSel8C2edzzD6zTy+P/w1qnkN+th6lrKz+oBTH wqGmK06dBo+J/G5wUyq5bpfXoxGOqJ8mGi821rsB3yrylGtw8cAKuxSt4pX8K3zb+4/BDAY6 TouJOQw02s/l2gVcuYLPaH7dlrSVfd4Z/swFuB3VQjVVPBcEF8Cbk5vNBgZTI53x+uv9y+7T 2FsMVxBceAlR9ucTsI4NEb+N0nx24p+edqECil869jDLlSXJsqR5CagEq4J3e9Zsou+uBzoq m7qcMCmOeZFstBvzt9d+K2b/Ajs52x0efvy3dxeGBkoYLelCYlSacjQtUgj3OW6WccVoWm86 AlIlk/GAc0099xhg3kA+5dFbHoAMPU6X5BkCuc50YxskmZoWI8nzsRhdi3AchIxrwx5m5KOP iU7rxpAMvekx8Yg00MgeFpMUESSraUxjwkW6a5HJ/Jo9Fc1HgPB5eHDo054bYpX7BY0+Ipy4 R2vdO9MEjzwKWxGZICYm5A/7ezYlsz8vkWJdLleTU6xV6oKoxRDNowc68Q3ugQenWNNGtslE hEdEUXD/ikgX4U8pWPHPdq+PX57XoBFn2Afdwx/67du3/csh0AHAGOuYU9b2Rx3GULxYcYzW odNf96+H2cP++fCyf3qC2H2wr0cS9vzp2/7xORwTTj2LLvb70KPrGKHr3N5N8Wfw+vvj4eHX 9Bx8Hlpj3dHQwviJmO6Xfbq3CoNO1am6kKaYLQmKAhZSKBdipAKJknuX/ypmPnw4Ox8ACyb9 aE9kbTX3V4wpe/9bUE7ib+BvAvaK+w+loJnTiN0u/fBw//Jp9svL46cv/uWhLRZ2h2b2s5UX MURxKosYaHgMYRVrTVOxEaUrtHnzzq5/uvjZO4Sbi7OfL+J1Y5H3WBs57riCk8p4OjVlLflW 5/ORJLA/dg9vh/tfnnb2h71mtkh6eJ29n7Gvb0/3kbOAV3yFwWvtw5zgI3yvhV82g3f0pfEa fMEggvXfrHV9aap4HT9iIbIxI8oOeFxUBxZcpxLpOIswjdjl7y7jH6/pLq1xGWTaKz9AwkfK HJyy4AEWAlkPs5tZ7Q6/719+Q2968LO860J0yZIvYCtfFPALDD8J1DGOtWTplDpE6qleAYq/ Z4TJYMzYh/OuDThxJdGa59toHNuoLrZWcoHNRD1VMgBi97YlHeeaVOFIG/8Gt+LZIvASHaRd laTq3s2k71NZgpuzi/PgTuUAbRcrlc5/ezRiiiZjNL2nZRmIHHxeJKh47R0nfHSXZAJX1pAy lfHaXHwYmpak9nVeIQOe5IwxXMeHqxSsrcruD/vwGo4SFE6ZpMSfDfA7FoTG/SLL/D9h19Ic t46r/0rXLG6dUzWZ9NNuL7KgKKmbsV4W1W05G5XH6dy4jmOnYmdO5t8PQepBkGBnkUcDIEVS FAmA4IcBcEFP6Zufp58nNc/f98GyTixFL9/xiNJFBu6+ibxHdPtUcnfmA10pHJQSNLD1HdAb v7raPlgZiGohpIhE8Sa5yQhqlPrEHfmoWPofn9RmTGOfh4/i9hnV2Lcb6LxP5/vyOqHG6oaM KR6L4YP9gZzejByvwrP17ffEaFQi8YnkEqqls4O33EmD0ehaDmaaPd2/vj5+eXwY4CStcjxz HqAIcAZkRxIM5IaLIk5an5He+rQDjpLpSdrMoP05vYB7XupUW8tj5fZ9oFOBPGMTM4145ZXz IVU8kaiirsnYFSe13/8cgGAcGAS9B2rGmQoZd7ZSBmfVZSa4N3uBA7fFArUBOxd1jZFfBo5U e1VGwpn0AgWjGpLE+MB8rE4EjlBHgesIyp55IGw2VNXhF9DXixxGA12k5HgpzRJumznqga25 pImu0yxEqHzPchdXSqb/Vs5OLCVxZqFIRYoQ9GJOARLEBdx/kyWAFFqqglInmL6ZRNGG/9LM Am0oFoM4+Zr0BLMtUg4f1Z9MFNeDkjZsm5W78ACl20nUZ02DUEZarzFoOJZJsZcUupBW4ULv zJIxKl7ondQtODXuOoz3Ed2MV8V6fXb2dnrFgGJ7ltcsnm7NVPcPf53eZvX958cXuIP49vLw 8mTZDQzpNfCri5kyLmXGjnifqO2Yh7qUo9Oatf9abmbPfYs+n/7z+HDy7dn8Wtj7ywXo3Ojl VzcJnNmRAxexO2UjdHAtPY3piW6J7AMid4zSezmzzkbVD2WuodUbSBEPlOx2t8MwqF+z2HQ+ HjuPajlyRgXMaFbrNUNmHilOjm7LOMs4XDYGsKHQ9W8lliUxGTalWB9Z8akT6n/W5eAKlBG8 QOqHdTwQSq+5/PKSCkQBnkgF/GvjwwA590e/Sti19txg1Bo9Ih8ZxJcEHiHLFN82t4gdl/Zr Oki1vAHwy5f7h5P3mpIcLo9TC6Dmyhi4S7dxu3OFro8MJqYSIDrrUbdwYdWj5jxiPRU92FyE MXeGqHcc2fY6INEkcY0odQoHi+hbHIhd01BbF1RT4OCHnqRa2Z2xPAcpQCIoCcFJbC9it/49 vR0oTka7pjUnDpY6CxoTNdQeZE4onn6e3l5e3r4G17qoce8qQMd5joe9wfwbztDvPRdR47xv ixxYk2wJ8wSvsIxJe82wD6xu3GYADRZWs/z4rP2aJBfltfC6pDkRlxXJYM1+dU1yMqIrmrG6 FSRQniXiv4upITlJN++CehzbXbTUhTpLJK+P1LjzfDlfhYtGlVrcWm8GpGgdMMS4yRbUi11R 3raemR0S7JgdJwrDsU+Gftxz6hQhGnuHCZ2MbTM4mt7k5HZu6oTl/WV7omp4jRkyQW+TtnEA pzQJo23ydAc+ETQgxsOy0G73nA7+HorBwplkJUQv37IaQNSlX/foLsVXKSx2WFsdhYyriWUQ jBqTG8UgyeuY+dkKRjYMAvJ1iUgziCp7h5HlvR8oBsyCE4yaQ9g4vK7sPLfbo2aQIsc9ZYTZ omO8+tlnDpG7//j2+Pz69uP01H19+4cnmCf4au/ICG4Do0Q41M6uXQ7B2kbRCFSjj8fP1SQb poFeIOWDyWwwnz6D3E6FoH/2tWpM/Q9b61whvRYkiB+YEFee6+Kq6m/UB0u4kFaciRT/8s+S NVUVV99RQDMUaUAzKlLsT0zVexY70TA6kAL4BbksAWdvAwgAQe5j7RPu7aX7H7P08fQEmH/f vv187h1Usz+U6J/9Rm7t4FBBngjwtuNaq2KzXhOkTiy9zhhGHghX6yVWK3d0CAlVeaDb+joX BiJC5L5dJCtP3CFrlgv1L6OpuKrK+HSwXe34QbJb4wGhXfmASu7eDBm5ylLueJJlASsflm2w 9O3V4k4DFUyM/jzZscimLBCPDz15VvpHQgcDYGjud1K+kOTY5FWK9oOB1uVwKZM8YmFFzLLS Pm+savOkVNS5jpjU4NMTP73Vh6U4GHQUFkUYPkhtEzUbRS0g3bFKA/Q23mGdqqcEupRlWcTI cGANvQZWi3+2B/EStwGeQ7UGUps0tTgGxr63eOpE+sVg0+/Lqq02LwNxK/JOWhgG9BwckOmr wxn7ypaCeBAnFYLa7dHppfmNv6Welue2EjUI2hkO4Nhfp42JAT08xbeV1btOCp6MWMDTuAAu FMZEHkOtvJVP/VM44HWgcHmYqHkTox9wnqPv/QLYi6RZJmgK7lCY+3zvFsEKNLymvjySnHsO BOTEEGOMZWzgGactrL4cyQ7q0vf7H6/WInFQP2a5yVGj0WKbH/fPr+bkfZbd/xe7t1TVUXat ponzPOfmYmpbfUWKLTT43dW31MFlgQrWaYxrktLkZ5qmdw4ClBKi2lSWzp1gRRsxetTcypls iEDFmuXv6zJ/nz7dv36dPXx9/E64+WD0U4HH4GMSJ9z5LoCuPp0xcwhqjKpBu4ENDhyplTWx zowVseK608Dy3QJX7nCXZ7lrtwUOf0trj0QjAhgVvuSKOqAeOi+czmjakhomEYDqGNgkAsfA BMPYWBPu4Odqe459utrBmE89NCJz21aTzlbNsR3J+pOMpEGs07Msv//+3Yp6hrgXM9fuHwBa yJlqJSghLYxt1dtueFbv7+BqXnCIZMS7HWnQa64OlYI7MGnGHNMC2p3HlxdtXQagVJSE4Puz /ERGy5qE9dCdu97O1603XJJHy45skFKM3k5Pgdqy9Xq+a3FVTpyfIUGAVqCOXQUQEHFc42pM OO8RQE1rr76MNeG5kMEB5VCjfv3y9PTlHQTG3T8+nz7PlJDvZsMPyPlmQxq/MFaZerbT570h 4W+zicON1Ev40mx4Rql8fP3rXfn8jsO09DRMq6SaOTvLrR7pM35l53b5h8XapzbTDXT9OgGe OOEct3+gqiWe4BCykZ3dCdXgcdSu4eZJGQvECQBeBxkYwW1kwozxpikwSr0cqq5rfTcw8lrS CeWbnivkdamRf84yzQ5DICeek411NMScaLcnDPemzzXfKhBFzW0tmoRqg5opa4LOWertjoYh N5tVAJtokIG/pAhNay1CgZppFaFIgO/pAFmlxmb2f+bf5UytFrNvp28vP/5LqwJaDHfrRmMy ENqArAS1gOTNdvHrF3BC37gpp62/tY6qUyqmtxMcItoML6nzfvc6qQGVdq+J9iSifFXYN2mL avQLaQ/SpHr657FKGF9+7QFMPUJXHLIMfvicNPZpcKImJYymqFbLtvUlYsavLuY+/eBAoA10 rsw6s1hQjuJeKEMoiTZVY1MY9KKty9fQK2Vf1qy4daT2gcdXCIf9PPv36eH+5+tppg2TVM6U hqBDLU0jnk4Pb6fP1mnMMGARMS6y3fpEtGdYxL69U5JWm6f9eBpnY7CkYrV1d9V1w+Ojfe5p k3szzoKKxuxb7SGxhx8yOsDl4S5pqGXHePj6eTGFTIxUDbd75oXV0p4bxTFPBhe8NwGASXln oEzKolrYd/gNlTuEhtU7FM07EZ2pY3MC1Si6PWXyx9cHy7ydLKOkUAa/hESkq+w4X1J7D4s3 y03bxVWJ74VP5IBLLj7k+R222UWUd0zaV1b2rGicdB07uNPBqYxDjUhz5xREky7b1rIR1Fhf rZZyPUfnIEmhRkQCOCbcNAz4L/RGsunydGcHe9vUCd1U9evSkdC36Pp0H7JGNui+6kRGR8Kw KpZX2/mSkQ4+IbPl1XxuaU6GsrSWp+E1Noqz2RCMaL+4vCTo+tFXcwQmvM/5xWpDGWSxXFxs keF17N104J6gE6poFCp8+weOY81VDrVesav1lopikGjdQVdLGoSwyZfuVmQoavqpKljdLRcY LcRcKEgqsDVe3ds0hq4WliWygnuyjxiD+TlrL7aXVgxRT79a8faCqE/Zvt32al8lkrK6eHS5 mDvT3dDco4mJqL4ueciNp2D4+JvTr/vXmYCzop/fdLqf/pblG/hwoP+zJ2VfwJby8Pgd/msv EQ0YurTX0Fo83CXABEM9vZ1+3M/SasdmXx5/fPsbbjJ9fvn7+enl/vPMZDy2oq8gAIKBVV3Z EeDanDLe+fHJI7EjV92J3bQ2oJSZrMdcK+cGR/kZbMRccO3/M2bL4PKSXKQE+VhWBHWqaA8X qkJMDtd4iMcE5V++jyDC8u3+7TTLJ2yVP3gp8z9ddz60b6xu6DncBetqFBGU8D0yRnibaQwa +uBKMVl6GFzJZRU431VimaCOt0w+DBs4wvwwqt/T6V5pMK8nZTm+POg5qh2L7x8/n+DPv95+ vWnXx9fT0/f3j89fXmYvzzNVgdGzbQDsOOlapUNoWDj0rM4EhUlMVAoEvjg2oucrpnSSE1rl djGuZxd3JvfsNEVHKpmjwnqOrRmM+meSXdvZem1xQnHTZEjyEpWQ6KOuy5qoVEmp1pDqi2IF 7zLqwTPJTTnpRdXILUb7HL8r9W7AT6WkhjX2/b9//v+Xx19Y/9CjZM4MzgwSkTBuUI7z+GJN 6OmGrraM/WDnUl1W9sX5V6OPGNL0g3Vb0erZq7992JVjd5KhwEYGN3TLmr5YPpQv0zQqTYiK 1/Dfjxd4ii+WC39Y6k8YBcvpqoc7DzyW8AtjI3ktYZlYbNoVHTM2yOTx5ZqOEhokGiHaiqpf v8VAhGsv0tQizZJz1YNqtqSmCKhsIfqGbA5waJf2ILKvmtXFeZGP+sz5nJ0o+cK5pjp+CGqk zs3YZru4XBKvt9kuF6sAnbB+C7m9XC82PqOK+XKuJgMkzDnDLZJbnyuPt9eS6pQUIncwFz0J NfJUB2TGr+bJxYXPaepc6cg+/SjYdslbej43fHvB53PKf4q/lNE/C/Zj75H11gKdywXdkKiZ iDWuDUoka1/J12VQCl9N6UP5kZWkax+BYGgFDWQGv4CrnOm29402CQr+UArgX/+cvd1/P/1z xuN3SkP901/apG2+72tDa3xaKTFO/VieBNQYKtoRlduOWd0lri8WFzhvt+Zk5W4XCv3WAhKi hJm8K3xtVQ9IM6jEr86LBMca8eqUnU2Shf6b4kgA1ArQle6k/iELuFMCqFqrk3YQgWHVFfmE rLw1YVOWJQl0fYKsc9Q6BaKiXRoZ60NKlgPFe7Wr2059Wa2e55RJB3XuK8m816YKXrUtvdIP AqrDoToZjuY0NMahGd6jmOCXLbkfjewr2+vTE2AvkhrX1QQ/fFgtXQnA+QT3AGSOz+WHjQX9 OIgYE81DREZcSCH8wSsJoJ1VnTTNnUm8S/Xran1uCPPjmRHMj4fcW4YqcOyU/pPg8EBNl+AQ 1hwh1mtioh6+RGnWd0wvh2qvUAoNwchzishEFpVo8R55QeN8lPC/LWUpr0jqEr4vHZG4Sz4s lluq1Dn+0tTqLD45q5vqhrIHNP+Qyj33p6whdyEYESTTa8rhr68RODWQ+dAPUq2cpE7ZG83V ES8DaqXCAYuaUAbCi3TnC7L+fsdrV4urhfsNJ45NNRKVPbLbJbFJxBN+pBaFjTPRh+OAPxac tVoWXqiqWoJXG1eVHnReHQOTE6pjFzfuVgWpulxS5W0WANDrf2iKzBbkFR8zoCZBtjPKd/lm xbdqxaAceP3za/9RVW1CpcKDCSIQmxaq9kbPoE59C3Ov+puMqY0yXDfwRcAZf5PEwqswq85V F/PV1eZXcH2CEbq6XDsvoZCVjbmhabfx5eKqdddF7HwzSlY+7DaYup1jJ7T52lJ3NGzumOgL F+L7JJOi7M5/ZMMWH45cMF1wp2m87+qYce+piq6hzs+MNaBYhz/svTISD67uUsrYzHmGQutG 3iFzRxKosd74tNcxmVCrJzZ+Lc7SAV+3waMpYqUsUMccJjv45EFBdQ0ovFPngfipKmNS0wFm lY/HL3zENnqd/f349lXJP7+TaTp7vn97/M9pun9nKZ36oSiQeyQRDhHNU2PKF8pYd4toNB6i Liky7ObWxJQ6BM4Jey9HW1Ue64hPk2eZPoqPYTFOGHl2HWut0bLYesrCp/hC680FoplU68xe jRVVG0p2OszhPBH9didST+0Pj6THHjx2+ZDhnOLZA6Ukf2O3UakPJ1Z0SPH6MIib2BxIb6HM 6VrDptHXt6ESAWEHQtrRLbEGo1PGdqMhq50vSHH1UTRdnyxYJfd29nZF1PmRlf15FJB8Gnmf oTb3NHegKT2JTDaYq++SoSoAZKFEcb9gAU6opIiDF2hF+JTU7jiOE4d+vlbuUR0mNN6pJc1Y CAVJcdUiI5og1xyMhbjQOx01Q/vf43xK+0r3wEn92h8WO0eqXFXjhOoCDTLu2kHZQKtcWxCI MP6U+gEn0hA07x1169oRqhus6qPUtOhGVU8lu58epANnbJzRSZLMFqur9eyP9PHH6Vb9+dN3 16SiTuDe3dSKgdKVaOkcyao16DB0ZBSlJO0QuCoFYGr9MQoOy2Ec0kHkpRq8qKFUTHOvCA6u rVVN2LdWpjc5zQg4g6cOLG8OLMM5JQonmkC48ENNgmMFB5o+bIF0VyzmLHBWiGXr8lDEdRmR qrQj6iSYwFzIOHNMYE7ZAPhYBm5vRCzDAJtquF3UE0WSZP5dVZ36nyydCz49rYvvCpY7sD0Y q0LjYCiKhiyv1X/wDZPmUHRH/fLqUsqOxIY5Jg2KcO2DWIrAl1BkdCiSss0ROpf5rZR2G9Rw IM43SHftyTWjYvJ7JneywJgpmV/Nf/0iquo55CW84WlCrUVUlcs5ioBwGPgow2XaAAgitY7B vbA9fWGvaRD4nKZJnfQgiJENInvSnNGsUccfvkYA+0AvJo9dKC21z8Rl3a14ieIiNILkim9s e2aibi2UxmNZNzaIVHNX7Ut7/7eewmJWIZzNnqBzm6RolbRLKbUjsXu1WC1aWjJjHLYx5NrN BC9d2K1RvkncfN4J7VDowwgaGWhjzj6hpM4FI4YfFbBz3uTxdrFYdImtWlYwuzDqVv8GipyH 8m0CVmi7iwKppnqmOTZPeGBVGpuoFvOisfEFbGbtAdUNHOh2SWsStthB6VgsKMVZnBQkALxV h9kc7Jkb2TdH1Q+DpwtJXXR6N4+n4TrP8C1C0Vp2PC/spbkRu1Jju1jhLUDp9reB2E1VWYvq bvCvHocMTmxhoyFfgeo9R0kzooJ+V5wdxSGnWcb+RwtR7xJo6JytI5u+FDOxjyGUr+HRSh1D Dw58ebxVU5VhZTgI+jlUHife9GwOmaBTq02l3OOwOFtSdzGl0jPcXAcDTV8xPP8YyM9lL5lR skTLhPltJg/51pJPfUg+9WElLWkKWxLp4aNo5IFYWdL8+HGxpY4xrOJ7O71gtbBP/m2pA7tF aUdE4YIQ9pIDdsg0EWj3ZIKjDPTPxP2tRs2+jih2EfoxDuoUQbGLjjSEoVBrJRWXAkuoValZ Ub1qgRyqeD2nF2hgBMqk+WIeAlIcxnG73NhnTB9zeq/KWX1MbEUyP/Z6waS0guLIuoj0+F9j 1Fr4fQbSXbMhuEQKek+Q13eUVWc3WLWWFaV9sSpr1x063wECtjc1yXGrKNrGF9tA+nIEiwE0 iC9EJHnr2UETNbjUWyJEviTDDZ3BGC4dBq14Lk7nMFyC1/iDupbb7ZrOeQ2szULVRoVgXctP qmCLN8I0YVnRBhafgikNKQ+gMVhigHVXlHRwuyV2FLFA7iKdMSR24vKpJ5TXdCMguRLt49fm lEapVjNrJ4rftM0cTEzDcpOxVWt/fjcZVhLMb3dVv8l2+Cttk6LD5WzPivrRZdkSERLMdk7W 7SYr49zFIbsBRL9EGalEb+u8wI4Sqy7I0tAkv1mRavjsGa1713bmuPpivqa3kRqAKOtAIyTL 1bYbgpIchJLkhqxaCsdUl/xqOV9RcTqoFD6BFfKKPkwTcnE1DzW8zJTBo/7Q+4AtmcvwdB1k Gh389Zt2H5wUvlV1lycBHBgY1YTGY5RSbeSoW4IC4rGe3CT7Q4O9eZryu279XuIowgZEL3Ir Pv1WWWxFTZm/QF7iW/z2eN4VZUXHK6RxbH2AcZLay4L+OeBQWJtgGobblVEAkxG27SFyBNn4 TnZjTRFNxGxfuab2d0eHju/vUA4keWvAeabjeLW+NLWAnI0g7PlEcyFmQA+h9ukE7zbez2Bj ds6DWLOdr1r3GYN+zHMItsE1KeL2kiCadd3p2GA4uo9VBiGLWeCxag9vROE1NVbWVV8V5Ryv tqvteusVAvLFZaBQKiDXFOqJ4FV2kA5NX0hob9kdpmcQeNAs5osFdxhtgwm9Kui2biAv5rtA C42O4ZXTie/1vd1gqRL0A7dgodMVs8wtN21TQymS229GgafCFjI0yprbamF1m/E/yq6sO25b Sf8VPc48eMKlufQjt+6Gm2jSBHrTC49iaxKfa1s+sjKT++8HBXABwAKVeYijrq+IfSkUClWM i0PEDTskgvJHDCRSWF1wgUsTVpnEGxHnyFu/F7Mh6PaGMr014r+2bZ8zGIdmuNlWBg+pM45G eBKo8uppJkTbtrIocOtkn2gF0LiSlQaMdkmAZvsonRsMP1Kz+qBt7vAwS/qTmq4nNECc7I0s gXYUJ0eHhAdwW+0zdsYPE4NPztR6nLVAAztPIQokKWrAB6j4zzihj1XKbmnqJzc7sRna9n6S YgYTI1tRFlJPuExbIH2lh0nQgVOBAOrI7cYBoDmhWHFLuo1RE+WRgXXbxDQf15DUEVR7YhGT LYmczTuybI3z64js6zjwsiX9BGtcihYJ1krc4dvIQQuWpKFrkMg7glNJ2BjuavE9tCU758xx UzKyPWbnbmWoypRuaRD6nuOx8ch1zGpqHoVG5JNYGK9X1O31yCI2isi/+fbXUAcVWMXxLWkP hkpaPrEkVddl/WI6XOpY185MtTtsrVcHV0t3LQWH61ea3R7gDvXb869fD/nry9OX3yHK98J5 lnLXSIKN52lDXKeafp0NxOHlEW89LUrMYunSsB2EBs9RKLOdCw+at95x0U5YiV5dXnTl7YXa Wg0gdV1rPtnuW/VAfXj69/OvN+eTAnJqzeBSkuByaK7A3Q5itZveZBUCV5KWF3UFMOmY9mj5 CjJYaCaky9tReXObPIR9g4GAOxMfPoPrbcs7psHwsbkbDh4UtbqgxHwOPK/azeV+Rn1wrO6L R1Ujrc/KFt4JYboVgyXVXCRYyBZD+FH3tDDRP4kVUX+QrQGBH2NAOQRz6OI0QuD6qDJa1gxO DmvVkn6MYCxU+Pe8yOKNj8V40VnSjY+1jBonaLo1TcMgXEsWOMIQTfWWhBHW3lR/TTlT284P fLQUp+rKUXXgxNG01Qm0gljCg14DQfZNXe4IO8y+Apd5M95cM3EowPV9E9f5JLp2nYfToOfN uTjg4VVmvmu98UJseN3MgapNV+0QAj/7lgUIqc9q3a55puf3EiODUk78X5eyZ1CIslnLDZ8Z CCgkEfP0PLEU99aM4KTlS3ZV3jRHDAML6OMY1HI+K014JTZEuLPGDkxz8So47Ol6QS0D2UV6 UNYZ2zUFnI2KA573hcq/17OmVhhdBbGqIxnq/lDCWdvWlSzZ8lNxLI+2CeaKQ+HFPWszuzbQ TLYLYBOxNeUuNlkhZ+YXdrvdskX2Cy9bqhGmUePQ0ltchmgy7U1MYNrQGSl9Jo7EjeEKeoZC zEJ4hnUN1EQtmrzL0OT2O/Sic8Y7877RAHrUfH9mOROxC1DdinPCpMd2I0TWBDFSVleIutQh IKemL845QXlDgI6CieeadR1BfV1NLPB0tK71wClzucAEtOlyF5RbUcJmFMKkOKJ2zBW7klL8 WCvb46E6Hc54P2Ys8nz84n7iAWHo7IjuNTHd2swVVxwGrYwXjx0bBhjmPSu6Sr+j04hgvttW HSf69qfjadrSNNaDNehoViZpstUbYIk6JqTByCk49NBtLwz4LAQYcitIh+P5OfA9P3QVo7in Bad738ekP5ORc9Yu7hYRlverpBjtq1CMw/COrDOU2dYLNw4MFrKuwcFDRlt2IK6Mq0qPDWwg +6yGN29yQ8FZEJMFHd43TYm+YdeZSE0C33RKZKRxPj1iG6FR0iPfBX6QuNKoXHZZJhMmOOsc 1wwUytfhmY+TwdoMdQYhyvp+iip0DLaCRZ55PDdgynwf9ZilM1X1Dl4tknbjTEf+eK97TtWN OIYWPSZ+4EpdCNILb/B4w5fi3Mqjm4e7UtBZ5d8deCd8p9Ty7ytxLXPj8oFmci25vLJ4f1pL bU1D24Yp15Z4Kxd+mKTY0cdOSk04vMhSw5qdPhLHqgh4SN0Y4Stgxc9d7uhjwOUcdMMlLXrO Cv2pziL7bpQ5XQyluixYKQR4Qsnq/p2E9g3XvefZ8Edw8O1YYmVT1CvtUAWOpRLAxzsYT5C1 tLnYgotNZEibNtPKdJNpZOy+0gLyb8ID9/4nOkou6bh3Oosz8Lz31hnFleDF6WhvnoZ1kJG6 yjBx2WRi7j2RcT/Qn3GaGN1xhxjDbmkcOZdF3rI48hL8db3O+FjxOAhwjzgGn1v4NRqrOVAl vaCKkuGQTsxQ1Io6ymV9c8J1AhrbyGUfeIR85m9uONXe0xSW0wy/0BlUduHNE/XhXDesGZSR BWuPnU0FRU8Sb0OwguAEyVAwpNsgeqeWkmubzKmYqFqO+/ba4WWjNEs3ulvFoSHE6mt405DU fRtkSxrc61dVWy1qKCFOao6o4DSOsoKo1/iRRLFdCYPVps/5yaGzVoXmtZAB3mUiMlwIr9DA 8aM2VZyiTgOfXa3jjX/cLusiyUNNezsamcXbgl01xe9WFcddbBDWrakCCup7W+dnndjcjM62 j0ww2wM/nXmcSWW3NhCzp9V3qSERpWlzD6qR4UKso/4Eg6mVgp35nx03Am1WU9HN71egLXaR F4di8NMzkkyxSyNU/TPgVzoPa/tbga0XXg7sruFZdwfvrE25nB1wxIkifHUCLA5dK9etDrGl S5LN7UNBhIrmKs42uaBZaMndBuAQCYc0hQQjTudw+V5WeYY0UtldAlik1cLkvsSRfHE08i2a QsLJEu4osY+YkmRG3AEKo7lF2ek+Z0eKEhQselAOvkBtfj3Y3kAJbIqujR4oxj6saFG0uIk8 PL1+kR5FyW/Ng+2yySwl4sLc4pA/e5J6m8Amin9tD7MKKHgaFAmqNVAMbUEMZbmi1iRXVCs5 /GGdwoZHTUhqggTmIzZZ1BjjVnc9zDKqsGW/AdhntLJrPtL6E4siLJzKxFBrmomJWNGz7x19 BNkJMQTo6s7wz6fXp89vz6/LW2Wuv+C/6H7HhueYvMtOrM5GD7gT58iA0cQMrSr9scQV5Z7J fU5OpfGg/Xwit63YMvjdkG6VUyJJdnSuOL9ojimMkS9Duzu86hf3os5KXStX3B9BS6s7WWpu mbI9q/WxLsnSF5Fl2ng/FbCf4gZEA4g7gBnAfm9aITePjcPEnDCHzWgPkQod0J7h0WOk5xpx LjhhmvHpIs56xllWF4pazgrgqNz8DzFYXr8+fVtaSA59V2VdfS/07X0A0sB0xD0RRQZtV8lg XmNMJ5zPCJygAzvo0yOOLcatkbPhWVDPyvANogHwRsleqqasVoa0ZDh1/VlGF9tgaHc+cUKr NZbqxqtTqZvV6yjNTmJmNUZUMx2XweFM//NmN4CnEjfeWY7q9A5g2HWakfjVkSgP0vSGY3XL HDWhliM7HRKTebE1nl5+fABUUOTglY+blw4qVTLQ/rWlrbKgcVS5Kz1xTn3uWxymFKIRtSFr 5//RMeEHmBXFCTUCnXA/JgwUd2jmE+xG7FPugItxm1ddma21yLBlf+TZ3owjjuPOievg6/N7 mzGGFG74AJjdpQO//Ha0awt6v9Otp8Uz9R99CkNFzV5/kUbX4o+gBljMPzFb1msIjnes63AN KXhXw45g764T7+BgAanIvIe1lAh58lTWjoO5kBeU+wp8P7vgUba6cBtrshNczxPj1QNrTvd2 cmE/ePr6jIhMi83bWrInHBxEidW033gO89CZYYP7o+uCjXFfQ9oxhjl+z3+1XCdMCckgc/YV flukSRj/7TJlOrHCeh8hZOnBFFATe7KbokNYyiDSPPwdWodxqOjcfXGo4LZX7FR4J/NC/Ndi HSnkrsL0oiOyNuOY30hd3w0jlpEigxSNfQyHzKUxoH6GA/dk0mSiEbLFnhjqBkGVNj4Qa8ro o6CQdxUZej0MoNhAbQNBQaZnXBEK2BAeFx7qOxIdjVSmimXf/nh5/fr25/dfRt3EOrZvcsLt 3IHcFtiT9RnN9PSncyJEbZhbcZg8D6I8gv4nRG34PLlpW4p7KnHiK9/gNjEOl8Vc+EbXUVom us+ymdazTZoGCwS8TphEkno2xfCUrCiUmxTwIL6xy3qS2mhU1QcdBt63t1atBTHWT+4DbRvf TNpF90oxENS9tIoQAkEHkFiGMrnCPDvMM+Hfv96evz/8DhF7h7iY//Fd9N+3fz88f//9+cuX 5y8Pvw1cH4QkBO76/9PsyQJmmLlkAFmcp8j+JB2e2pf8FrziaNXm1EVrwKp94C1GdUWri6sD luU8VrStSzuNRlopOqemmBZosU2mW2Y/cjZ6mBpXZUBTb2jGDq3+FlvQDyFyCug3NbWevjz9 fHNNqZI0YOx1DqxUy/pkTYIhwFxfgxrHrnrX5A3fnR8f+4YR19rAs4b1lW6iLankdLesveQw bcEXpDqRy5o1b3+KSszV0oaf7ipc7l9ZkdsldDsLUuMFzN2h/95hgfXtHZbc8YyBoYFIWKs7 fj4w84excSitmzi4z+vkFHVGkr99hehCc2scpN/SzHj/ZAhk4ufSIYFamFs2prfc+eAzIc+A l8Kj3JiNDEaoLtXF2BIZJtSU0R/PP55fn95eXpf7A29FMV4+/wspBG97P0rTftzj1fj/AVH5 HtQzxgcwhz9V/Np08smblCIYzyiE5314e3mAiDdiWIkp8kVG3RbzRub267/0xdDMCeRzpB8t pqM+zKG+xqtKFbrWCK048MBx2HZZooaVQ/aSSVnO4yVtCFNiUaXltjctF1SFy/z+9POnWLRl FshuoIpLS9T5pALhHsa4b1K3ZtesxV8XSdjhgEUvPhoTVDIQh5dGCdZ3cTAFQ2JX8rQZXNaZ 311uKaLpbsXA+zC0ESi7rXbSE9glvqFfUEXlabLIiq2VX4Ch79/Q7Vfm/vz3TzG40X5SrySc FZcDwMOGRXBbFHKgw6h0F1ZsbFsr/KsJwyXWMm3ekiJI/WVsOLor/1El0dci6qq33EaJT68X q5pTbBljkMo7ruXYFTugK/2P2elRnF7rxUdKMHC2hLwVtLKfdRk2II0e0hhpOHU/6spG4mmM tbgAtuiFiY4HdkHsRwsj1fRFIalXmoaRt8hZkLfbzXJiCUnnvZ5Wsrd79OU8dYRdUCO47kmz MtPatWkIPtEIvP73cUM4dYNaFmGAzFV4WLmonLHY6DLOAFx9/W9Qf4xLtf/hf78Ohyj6JERr s60ELwU7qk6++GmwyTizlCzY6MF5TMSMMKlj/hUXXGcee5PSS86+Pf3Ps11oKZYpfz94kRUD s+L+TgAU2ItcpdJ4sNlicOjxjcxPY2fOqFWQzpF6kfNj1H+KyeEqUhj2han7M+H03QZJYmwV MDhSD889SX0cSCtPd4Ip3fJlF2aTZJwWlAj/ckNXq0B2btv6jlPtJ54teKUA3FA8SRulkTw3 iFysFB3VHzG+/CjPuBjp98nAC23qkUm1I5K2waBHitPpwZLOcv3G8QC+mDuTOHLmn4LEjrNl Qs5XQDbfocT8gU9FBTN4b1kAsKxO1A6xSHnAcCWzwWStrFbNR/MZPY8RI6yFPHB96sAjh4aH zeKRo27TJEiWbW4qBSZuXoSx6bZXy0qa0q3kJdp740c37GsJbR3KYY0niJJ3Mkh0AUgDotR0 wjQNLpqHm2Q1YyWpbLFxbrAEfrIcJvvsvK+g4YLtBpkI4/XxEul45OE93/HtxhTjxwOx6VJM /hTbsKHJUcRBIXAwvXaoyz0VMwK5kB5iOueEn/fnTrNlWkAhgpXJxt846ClGp76nB5k0gcgF xC5g6wBCM4LKDG0D/DJi4uDJzfewVLmokoenChC2MRocceBIFY2xLQGsPViRxAFau2PKK8fD r4nF92wei2OXUT862LvRHPq7rStGC6xcueErdKa3lXkXP9D5rUVrUbIYPSPNuB9jI6gEl0bM dH83YfK0tJIoiY5CaM+xb+Fw7EWYelDnSIPdflmmXRKFScSWwGg9nJVIU+7EQZoiTbbjQlw9 84xXSIr7OvJThtZeQIHHUGefI4eQrDL0UzHW1r6T2oPstCzOgRxiP0SnC4kix4XhyAEqzXeG qa2dGOkfC8f+PDKIgd35weoIk/FmLC+oIyRX/LWRJDm2yEQQgNgnkYELQOBHjuw2QbDWA5Jj g6wTEogd5QhidOqB7BJ78Vr1JIuPrLoSiJElH4At2lcQ+D4OMZNrg2ODrJsSiNDhJaEtvvdr PKGfOCSTeY62odirVnl4EUeYpfOURnXaBX5OF45Bp96gMbKt1jTBqVhH0yRBqUhf1DTFRoQ4 UaCjj6arI53iU7CmqFClwUiHCqqjDNsoCNeaWHJs0PGsoLU6KBsBpE0A2ARo/U68UGd/wniD X+9PrAUXcwJ/2aPzJAmuDdB4xIlsbR0Ajq2HSGJSkbnVlp3W9H8x8eFkEKYCbNiRnPbFbtci 35AujAJsi65pIA4+sWOlC7YJpu/QOMLUR0oyrFobx2IQeEm0JpvBWrDZbJAxAOesOEWmkTgX bMQ5EBnGAonCOEHWx3NRbq03AToU4F5mB47HOvbxb9mB+2sDXOC4sCiAEI12OOMF0oWLe/1J xKKVn4TohKmEtLPx1meB4An893nia4C+ep6KR1mxSShW8AHBFh+F5eEWWUiFLBbF0hiQogu4 xPGFQkIh5gNp4uCcJZhMIORYsb9h07Hwg7RM5dkKOYgw31sdDoIjSQP8Y9G6abDWuOSUqfsy hG7aQ070MMBHHy/QB0ITfKAFvrtz2vqrC6FkQLcSieBKRo1lszq+gAFb2S4k64v2DEIrlrWA 4zTGvRlPPNwPVg+RFw6eBLHkr6k4TPhoTEmNwwyVqwOBC0CEEElHRqaiw2EArCQdpayTNOK4 AbjOE5+Qs5SAxDw77FxIJaFlrlJdutCHuGyIptkApnELHeuSjR89hwuQKRqASQCjnW5fneB9 ByTf7HZz+G/PZl4EnhgBiOcHTlrAX3OLm26MrEPQyH7fXMAFbguPPlFPGAj/LiOdMonHCqFz woMg5SHnHxdmULbXdVNkHHXYM361KAqCT1XDSgoM4B9b/rNawP9HXd6pw6zhk8YVw1coR1ld dl31CeNZjJ6zeqY0N4LyEy0LUtSZuQApjDVFX3KGJT9PBsEabrwbmJa8fjferuipActqVYbS FIeVylwzXhzKRpvkI8WyuZ/Ip+aa3ZszRyBlS93nTQORHWBOlAjXaGyi3JE+vX3+88vLH07X j6zZcaSUw8NSHIgDBJjPfxo2X+WUGQc3IVgTqVse7KvB//QIIR8/EtLB9dayPEPcLTTd8oqm OQ/74e3xKhOcvsPbaunkS+pl0bLi0xniYIr20IjlRXnPG8hTPllNKJjVOpoP4ETIQvZnUpmX Vo6vWBsJMVsIJ9olyb6CcJBGoVhe9DvC2yJA27E6d81YZHyK5InIBS+COFZlrNMH8E6sL0b2 JA49r2K5XTdSgZzqSFbUyUoFKFPwiNa0MAftmh/s7C/SxM7z0K71tDIssRpPCLCq9sZurUwg XS0mT+N+6MRPF+g0pASxp5rEyCsvhMDg6gCBJsHGMwstRLtokQx4mB9MnlxpCZYwyZOp3QY6 SIsGYZRtFtQ0SZbE7YJIs+LwuBykVSvOLSEy19QiTStiV+pEthCYwdnOpEg8P3XiFPyqBb6N j2YzH35/+vX8ZV5+i6fXL9qqCy+fC2RvKLkyhx4NVN5JRnAYyZhLfvv6/Pb1+/PLX28P+xex 6v94sWxSxh2jFesUoVVzlsIK1rvgSqlhjOT19OaCvfz4+vnXA/v67evnlx8P+dPnf/389vRD D9GuGw1DEqztjHc6kGpBwDG5nvoSNcaiIOebUJr+5B0p9+gzGfktvPuxEzfSmVkcabCSNKsp jAyO7y3bB0mSr26miI14vU0mO9MBdRic5gXNkGSBbP7qVc0KgtbO4HBlI3EhclkJz8W3ALar M3ZYZDNWCGI8FxQNM6mzWY+fFIZaSdO/vr19/e+/fnwG42FnLBe6K+1QakCxbBGBlrEw8Q0F IylGW0e9SJI340GaeG6jdWCS/mM9NJyAhJd2kjJp6VUFoy3cykJFOjDrx7xwyOJL85Cb/ZGU /wKXL9iRwWoeJRtiScW4umuAcZdIEjSeOQAFrhON6GQa0XzydeDwKIKRIjRpgkk9DtESULvE p3PWHZEnJXVbgDmzSWCmP+D5+AGtunJeGFn64sCvrtZVrMODZ6O5ZkQe3N/93pyFgEnj2II2 RgRlAKZXMxpN+b/yMGKEEGNvMZJAZ72JEszsZYD/j7Fna24b5/Wv+HF35vvm+BI7zjnTB4qS LTa6VZR86YsmTd2uZ9M44ySz039/AEqyeAGdfdhtDIAXgSQIkCCg3G6IYre3yxvKHadDL+/0 GGoX4HROAO8oyrul02i1mN15e9obOGZVlJcowlH3NyGUM9QlvhAL6UlzIfCIe9VU6+FqtV/J nTv4rlPOhdaXaEQR8Hk1JyMyIlZGnBCgUtzcLnbOQzGFSufk2aPC3e+XMGGsZY/6pWEUBbv5 2BWueom95OaBEkIr0bB0NpvvMAqfj+dImBSzO+/sQ6cz/bakqzlJ7RHvHcoHy7KQi8l47omU p/y0JvRdLRVjT29+8EZ3oHdjAto6e5nMAfjy5pZuv/9G+HTyLYFWsc2Zwd/dht5NqK4ZLu46 1BTwHQbE00yPLtvZ7u6E7DGsNkRfH0nMLbBNJtPbGTmDk3Q2n/mmh/FkwGQgnVJZyRF82uIo EaX4mmfsyj68TZc3Y0f5wDOViS8ea08wt3jfHcQ4PG4fB+hNlNEaz+bIg0zuCIOSALSJUYYK eR/Bjz7gVXjMDkhGu49CsDIHy35Q/X4dvh8fRo+ns54rRjPhsBxnKYaD6Ip7bD0kbGPYN9Xm X9CGYi0qDITxb4hLhk8YPqaTYUlRmV8TcfeMY0CV2tBuRBjhS52Nbaa0iDZ1XyoyzF3KsnVk yjE0VJsoQovOVbsV2109W3VDpV4yxwp3njhMxQi62D+HNa3cpqgTGS3xG4Z+qiRoTGQyZmG+ 7XAWz7CXfp4hS/oHbFpqpOE4O+L0kwnZziYwzdOU/w9agUS/uywbwMky3baH+Rp7Hp4fj09P D+ffwyPtt/dn+Pc/0Mzz6wn/OE4f4dfL8T+jH+fT89vh+fvrn/3TS/7++nb6dXw9jMJNMFr1 +B5dnU5Pr/iGEqyew9PpZfR8+Geopadanx9e/kIz3nm+ydbGAoWfeNJIzk6FqyhVVGHS0Kko DRfUnSjinBzqCGzTJ3tKtHlsdQC+J7VgGzPlGIKi1QoEiif2I6rP60o/yFqDBNBzJXQAFTZj XdTy00SLmIFIuRUVj6MypyR+WGoHIfADo46LJtSfFyM0BGbVOyrQhMIqJ+iUfvSjE4CGlqzw uQTdk+Y+lV1kCrN5hK8CErUKMEwMcUczIPMNRp9Ocv5pMh6bHUtyFjawQMPL4vD0rKosPm0u gcdwczs8P56+H86j03n01+HpBf7CYAbaGsQibaiO27H5UKjHSJFMFvQrhJ4k2xVNBXbq3ZJS fJAKRHhkKpsDVN2xFRW1VyIRLAaYPnbRFtpIalVpeC7uPSX/TaPNGsMYqUky3BiBVTn6g71/ P55G/FScT4+HVxBGf8KP5x/Hn+/nBzxLMRmMyXCh2KWGNBwlx29nlG3n0/vb8VkPUAhz2TwC UoBGVqzyBN9p8ddncJbXm4hp6ncH6Pa2OQnur2g/zUwW9kQB4/eJJ3S+mht3upNWD8FMTzFz d+ELnrOiqsuoicoyLyl8nrYbh4+gG1trYawjZ6ls16udPT9aKCxRToo+JFmnbG7qlB10Qbpu dciZkTYRgXWYmABmnuUqubdma9ojDLFclGUtmy9R6qyQLzvqvhUxQc5jabGijVbVLjQNXnQR qtW8DY+vL08Pv0fFw/PhyZIh7VEzUXjAGHWIPsnfKDgfv/8031UqVihtUuzgj52dr9UgjIUU 8L8gpW1VJSRFtg89QUuUtFVBNv1oERBxuFSHV+eHX4fRt/cfP0C0hnas0ZWZErKT5EquE0MD GwlPMUufxkaAZXklVnsDFOpPBeC3uvDeRJJYVFgp/LcSSVJG3EXwvNhDn5iDEJgYKUjM+Ekd roTNqwD1N0HHribYkyG2gU7uJd0yIsiWEeFrGVRp1LybdVThzzoDG6mI0AaMKNUHvxqsKrHO migD7SizWFbFA1xvJoB/WgQ5IYACulYlEUFkfXmue8TisEUrkFjQY926VuoDrwOLD6AgtRE3 9IZThseSpI2HHe+lsVETFugUFLM3lUgUl6s2DK07nf/q414R7h84EZTo8fGoSOm3F1hwD8b/ lM5zD2hWmpObgQICfLZng0hlRRuDgATukQkncdrgOjEacADZzWRitRavPVNMT+6oF5CTUB25 06Vafd1sVIHs+4kB4VzgEDTX9mNctmJjtokAokUFdtqz8PRsE7fme1kELUmnOFxH0XI8v13a AoaVIDIwnHVGBqpR6wBDBDiLA4FgJyRJlImaeuOkUWHysy+1KWk73JoCulzqa2KbyCspWgXX h2XVfjKl/NxbnNUeQBrunfGIXXtmG+Lo4ZIze9rOcHPxNSLZhpH3yYgTzhIQspn5VrlC6toh LkTTBm0hmLEWw+yC9Ocrj+RDsl0XilAEIC4c5mVRDruKoE77AHu/L02JPAtXOwcAKjw3Te8e QR8jYsfyPMzzifmV1XIxnZmiGFSkKDOHhpX3xu8iNcvAMklbVcFaPAgFtYWlTbQhXe4MGl7L Svc5WAWtm5MLaRJ7xbXgNa2aaXjqJgOnQCp5vbIrBZ2YJsdXJutddTPXtWhsxXlgrWZEWdXM Hqw0wgwneeqZwmkAI7MzB76DqXOytaV29ThXNgQl2O8yjsjEiTi4dd7cT+7GZls9dExC7S1J irQgI+Qq1t5OjOAL3eJvEh66OiICecKk7M6QTYwWwMqpji414J0YXlpRXcxTBMXWeME6INoL ecoJ4kIyXHQS5dXD5avFi3R5dzNptob/6ICWLGYlozCDqwOFWi4XY0+XEOm5VxqoqIgdbt+H S1R39NPZYjYme65Qd3TvkmI599zIGUS3ZNSugSSvpmOSNwUaVzRHtdtOotH+ou5qs7ZTijY9 DS8G7Vs2MIi3SUHhgnAxGd+SI1zyHc80MwO0UDy10VYGHuL3ujY/Pb+enkC77iziVst2D5rx qJQ7ySTAYM2z1jlZ8jJPEuzHR3iQGV+jT4sb4xyWokNjQcgKYx22ftRg5PWHQdShQp2me7eT Bhj+Teo0k5+WYxpf5lsMq3yRYrA7gQq6Qp9Xp2YC2YfjL0qwH0tz/yeoMW0QnsuSszrJ19SZ tMzrzIyjj4Aml9LvxCQzw9RvY12C+e8Mcyw0WQM/hog5VRll6yo2sCXT8gPUsRUBBEp3kte9 mHk5PGJEf+yDcwGFBdlNl0Nch3FeOwm+W0RZU+JI4VDMOgUQKDzRzhEvyXzdClWDnZ/YFQZR ci/oUWzRVV40q5WXAC8gSirxW4sU8GtvMgOGWjIz1acCq/s0X0XFdKJvyApm55hHIAzsOs/K 9ulKv0wuMPgQkzzC+4eV3ZUoibgnZnyLpia3wnxtU2FZMykNREmniFb4FRn6DFFxbubfbH87 X7GuFstZacKgI1ZOSgXdRyag5nhIyO0+b1kC4+7p1XpfWlcyCBX4HsICVRag2oosZpnd00wK WKDm9QZiEu6LzKWwkbNowXDNN77BwQ91l2YPbcLPHgT8KIyrygvGsywQX9YpSP2ChdNrVOu7 m/E1/BY04EReW37KKEvzWtLSsyXZK69YD1tSgf6bsH/ZzExzzDgf0ce6igA2M+HkKzZIsoq+ 0W1xpaAPZBALCnZEZRNCHKg7+CAqyc10TRr4GsuoJMgGumIYPdZmRwGiDNR5X6kEGle5Zi2B pLbTnQkr0YyyFwuY55xVJgzkpLn+FSyVtf6oUwENKYu/HCGhYgfZ2RoVosJJBpsdeS6qKOqs SGrrw0qliZmSDHOmMumV4irl1ed8b1amQ51eV2KT282AZJLwLZ5GqhiESeqUiUsw1NsglZ6C NSoFTSFnZg9UAnELJISZchOBOwHTygR9jcq8+9ZLZ3qYNUP1UvsQ1AJXGrbvZJu4DnwbfFJc LlmVxwulJqFPC6HuFILeoDpysFAdTUildqCaUGkodG0MK8ljLsyDfxPvGNVdIm8jUADCVCrB mMkm5mYTJlnrmGp8B8syWPc8arJoS3l7tb4zx9fHwxO+Mzm9vyo2nl7wQto4vVcZtrvXt52q T4yJotpnDH2xlZuTtFhSre0uAqjZxrDoE6tKhypIlN0kK8+E6OlWMjVbhW1T4oHZGgPl4fse K8Eg0qQevR5xWzUwAVs5rFNzDtN48CGNh/McVJVe3O7GY2cAmx3OERpq+BkPUOdoReXjJqtR 0BIv+oBhTVUR2KrCqSFBpaXKOl3o2/F0I99h3ui46LpiMBFDU04WO0R5GY00s8XUptEoVjDA 0IT7rTnJgfzSX3dtXHBSemcT8blGHXVH4ClfT2ZTihcyWU4mV8qVS7ZYzDF5tP1B2Bnz2VEP bV+GmVIMwCqgq531+DJ3uxfM/OnhlcgsoSQIt8YYdndUkkzgNnRYU6WuJZnBFvK/I8WBKi/x XuD74QV950an55HkUoy+vb+NguRe5cuS4ejXw+/ere7h6fU0+nYYPR8O3w/f/2+EeQz0muLD 08vox+k8+oWuqcfnHyfzQzo6SwS3QNtbU0ehBdlqJJfP60Aq4xCZhcmomlVsxQK68hWoD8Ze qyOFDI3DLx0HfzNHhvVIGYYlmYvaJtIfG+m4z3VayDivaCxLWB0yX+N5FjkKMkF2z8rUW0fv 5Qms47612dNGGXAjWEzNgC9q9TF3r8NJL349/Dw+/6SSlqmdIORLT4RBhUbjgVbUAS0Kyy+7 hW0o6TTAu5x0SwKZgfrDjXR1LdLzQrIrWYfcbqqf4ubHKDERltRdlNrLt/pLrx7S2A9IL4g1 C9eevGYXmrDGZHtWgrv2je/Twxus4F+j9dN7H1ahdws2F7OqiJDpAKei+6gdOBYFJse21K0O 2tgcGzDUx6o4yws3LgxOL5X4kpSlbS5AZ9L3aSkzT/pCjci5HNFw7eWOp3YmSo6HsterZ+X9 DDZpTx3uuRnxFfFMj2isYZSOF0fMFipdfkSxFu1laeTqxH3dBez8OxrVCYx0SaKjtIhs8d5l daxCAZzLSeRGyLwkMaJgX2gETR/BsqC0TgvdkB7feneXk+lsSn/JcjI335zq80bd316vWxRb T2lR19eL3kd7WbAMA9F7qugoPqgmkYL8tvs8EJghlZ4XKa+aumUL1bS6wfWKpJ4ol7e3ZFhX i2h5Y+/IHW5XeyduxjapY/x1iU+T6cyMN6Yh80oslmTGc43oC2c1vSi+gKBFc9JTuyx4sdzR kSN1MraiD9oM0ROVJbuafVOn3qdBTt3YazQVPRGUH9hn49pKw+5AyDnKVCd9tqbTns7lwr7U IWjSTGQRPbpYntsme98jPMFoUrrgVsg4yDNbJe2YJOuJo/x141r5pnpdhLfL1fh29sFE7nWB y55lHgEQznvK+EvFgvbQ67BTOmOMMiPCuiKvfdpebaQtn0uRW/7StbLk13nlDaumKLxGVb9H 8P0tX1haDd+rcFMmUITqlNkEqg0jSuzlrC6pQlALEra3Bk1I+GezdiVjj8Ct39PnxDEdK3R+ iDYiKD1vBVXP8y0rgYPWZoS2oG3PYwoSZSOuxA496C0WSLymXm1N6B7oLJETfVXM2TkzE08e 4N/pfLKjn0IrIik4/jGbe2J46kQ3C0+CC8UwzDgMY4DpF6yXDZfJXvz1+/X4+PA0Sh5+Uzki sZ4iNi61srxQ4B2PBBXMBXFtfiMr/XPF4k2OaN9I4YnH2NKYWi3a5mQL9TpZ2iToRW26mLoU 1Om3RoUf06h74ymB7Q2wrE6b9qZcAt3A5cP5+PLX4Qx8Hg7HbJHSH+fUoc8CWZeuat4fj9gf V+zYlHzMrUydjVsRwmbWCQtGTr2zVKwg5F1h004hbRMkpo5i03A+ny38Xwr7y3R6a7XcAZvQ NZYVauk3VNf5vU9t69PB6paTcqxwzpsSEaCPZC6Ni03E1E2EMtOSjk1mnxetmogARQ5I1oG0 d9hVs5I2pLJra/9cOVO9h3ebnpdPFzrG6QtwgygPIt8Mu9A4PLhgHFbomIEFdNNlBhvMR21H kaPvXXBFjIczH39jih56/bnah9SrJoHN7MOOdWPpqyO+chujkXWnjx831k6TQRqd/lGvbZ5Q 1v9WSVKr3y+H/3JX/Ff7Qn8RrX5CdUVqw1a4Y42nNrjm0lz88NuJK2NpNWHjvRlWay0phDfH br2lNpfUiKmS8iYw08JfQP09zeXwCV9eN7WRkgyJO+WhvTFSD7TbN9ofXn9gYet8FUEyjI1A Kj3Ilp2IKEHBjvEvkgFDUS+XtdqTakUvc6TZBpJSH9X3ixWs0NDuWu9K7Cklw7bvXNoFeXDr iUqC2I2KTWB9sY6vAyOjKcJqGXMbEsZiUeaJRdkfYBOsrnIZi8CXkBsp0kqfRlEqwfwxjsd7 mC+AmMq/K9+Oj39TlsaldJ2h6Yn58erUE+0Lg9+1s5jqq7zMeadd/6R1+6EGPqWDZHQkn9Wh cNbM9DS4F2xp6BMD2BiEXtGMtuq6coCoy0vlNE3Bmj76m44JStTaMzR24i2+9c3W0SWnOFBQ bFcFr+b3UxRMzhY3czoUuSJQQVwo87PHGglZFBD2pJul7kOvoNvSDGeigG3aXdoIVQSeiE5t 4xh+6MapE8Fz6tS4w87nevx+u+x8Tga9H7Az67sQuLBZgO7SuhXQA42ISD1wqWcc6aZCtMHE xSKxEIpfZnY9He6wy6VakG7z7QhZ8W4U0A1911blSaPaztdwSqcnUdguxJu8MS7DWmZUs7kZ 5qydpN5MyQrdZc+y6qo4w1hQNjTh87uJMzmHAGju7J9TeTEU1nJmb2vSIqBZ61PdZn57Oj7/ /cfkT6XFlOtA4aH+d8yuS7nmjv4YXIL+HHbhltFoHqdOr/Htu390MGrrMnBz/WJHqvPx509j t9d9LWyJ1btgYGDU0oMDDdW8eTSwoADfe1BpFXowcQTKTBCZ96UGxbVHkAYhN6NKGDjGK7ER FeUYbNBZcRCNz+scbIYMyMeXt4dvT4fX0VvL6WHos8Pbj+PTG4bnUFEkRn/ggLw9nH8e3v50 JPuF9SXLpIhIV0DzS1UIJ+/HFgymBVEHXuFg4NP+QV0Pnkz2sC0xfGjpuuZHIeMNq3L0GpK8 rAMLNThKXTqDcKL5suJN+wZaA2D+mMVysmys19GIU5soURHY2527lF5igHp0GyBwn/QDsImy tfFIH2HdgzO1QWdRIk0s6rIaA0FVKBmoIetQd/5oZaMA2EJPQ4y+vToZBk+zjxC+wJaGVhc0 la5T2iocaCgWbbFKOw5ZB3UAppoTy7rrz4Vt/Ol4eH7T2MbkPgN9dGd+CvwwjzEH7mLgqlCr MqhXmidbb91gpXg0NtQgtwqqMbveOUe5GC4o0U9H4vDmps0XfWGXSLHXXAjfKbRxzwhWFheG Iz6CirDc4DWvKKn8w0gRggbZUZi1MTNYF4JAsPNcUjH16i7Vu3ujDAjQyHYmpChrM24qAtPV YkrFnMKJrYX+0qCKAWp8NsczjIxrfXdRRSzLZIBeC7zRUQUYIIk8Uu8IRFbouSA6aJrqw6MB +xAbzSAROr/Jx/Pp9fTjbRT/fjmc/7sZ/Xw/gF1BhMWL90VUbshOtygMnVn4jltkxWB+U4e+ u+VCC7bmCizGMfx/6okxBsg4pL3GWQKbhIo84i0ta9B3WGE9mhhkJSZU/Qjvq7xHNsyjn14I kog+N+ryueZLny/Pqv4sKhBDV7rYk6hUObSErPgEcz74viMuWqcGH/LqlSniPfXC9sskut5f 6z7qgPcFC/3HIpd0qyHzZAHqQ/1nSb4lCaIoKq72Qs2Tq5OIYsJlihYCCw/rEsc8SHNDbqZS +DkVsS9eJLrVV6y8ysTuPCSomnJ1D/rLVarYx8eewL8W4UN5WlyLcs3jSuXQmXku5DtlIKvG 4/G02Xhtu5ZOPd7aWJqgRbMJKtorumvq6qQpUu5/44gv88uKZmb33IMYlX68d2k3KZwyXzxn aup+tlmnNX220fa49DigdxYoPtoASBZ5QmoUG0crJlgiPGMs63IFEhmDVsyaoK4qj0N6V1Od icpbV5rsGgzIftkbCCZiX5gRx6E/ymysO8wLvBAFPZo8LvM0urRGrWSe3KNPL2zM97X2SDrG REOAw3wZBdMVyfbEBXGfLq+ff/06PYOieHr8uw079M/p/LcWBe9SopFiPpsb0Q80JA95dDum fRV0MokBh4CP1NdoTU3TQupvxRHYxT/2dCDb0bJGI2mjXF9v2Yp2oGN29AmdTiL4jDpyibey EJl+btryW57ez1SiB6hLljCrl9P5zOBBtPn/xo5suY0c9yuqPO1W7UwsWXbshzz0JamjvtyH JPuly3G0jmpiyyXJtZ6/X4Bkd4MkqEzVTDkC0LwJAiSO2oSKn63+DgGUPizUjnLYsHWKyzzm txosRnGJACzzNwRp3TgyencUddqwBFGqCCqHRx/et/m5g6HASDdclFwxpOX2ZX/avh32T9xV bBmhqxUGr7E/fHs5PpNvpH82EP6r+vt42r6MctgfP3dv/x4d8Wbov7sncrUtA0m+/No/A7ja B2Y5/mH/+ONp/8Lhdn+mGw5+9/74Cz4xvyFcLdvEbVV6/PUfJm5gbR6LtMtq1yt08qeWdqeX 9WT+O5HHT1jBtnkWRqmXEX2NEoHEjXwKLWk09Z6SoJVRBdyJ03wJHd6diVx/jpq8qgI9yOyE 9Ug29FceyuQGZIOHTldA9HHCzEBW5rlh1QpykbqEDa2h8GbCFwXuRYjL6S3PIBUhpj2+vOJy xQ4EVg6KAYWXp+eKd7I/hS/rm9svlx5TeJVeXV3wO15RdLY6/J6GvVfy2mXs+CSrecOmFZyI PhuaQDLu4UefXpCAVJ4SA2LqxQP8zEEPNOIm/+ZKLxAOKbMsAJkaVcePMSApevV5mzYrqT9C XGD4D76nZYT2ZfCjxjghkRYBQeK8evHllh0/ifejMnEEa5AEcbrhl5JEo5NyfHeOoAjGrlih kiKNKocsJvFFDEpEsHAsD0kDjG5WzPlTWVHUqeNhS+GRkzqHuI6Z5BwS9XCfnet/Hc1LUG+K lJNzZtSKAH60M28ZGVGzEVyX8SpmI4chFrPNRiqwvfmlCsNtnXTF4n5UvX8/imNt4JPqukrZ 5ymgH6TtElM6oKGhjoIfKA21k5ssFRaEDhR+qW0GkQ/V4+W0VHdKku3dHtAk7PEV2DJIqbvT nonLU3pkT9eLBg6p0s+T3q7Ce/1x2O9+UH4OZ1iZs7Ffk9jPVmGc0ihbynOuSKl9VRYiQvsd JF5sUFD3UO1HSH35s1WqGxjBsmXaJs+RmsnmVC8cpgU9Wotb00NBvWOgBbUT76GWq5O59WTg 0iq2Z2hGPRDgRyv9541HG4JYNHrEVcBUARf1d3d4EZFRraM/ComUAj/anEYE6CMAw7jLBB+9 lJGAxurT4MtB6HvaK0JMXdLhp3nQCFDgZSIDJN5wZnA+RrMYtnkfHWqYP3TQBMV9hrbCGRuN eN0Gs7lZCYWSaMVEvcznILFxQeuHoxvaJBa2h5PulcaDpczOsH0+PI7+242zFEY7OXW2+7Ud SWZCBccA+h21awyfIV+uDIliwtvIAubSMGdTIMz7hwGoA/5qo6OqoqAp+bdCIJlqZo8C0GAk n7wUbTKqnf6jaqeuanWiKAvKe8shQqdxWSB/80Ni14C/TLsvtC30xZjrx1QM84lWe/x10jcL pRAY3XNizEMHa/MJ6zra40VwfPtLld7Bq5YJm5SWUuk1+7Xdh45rxknf0m4oJoLYAGCjjGIV Ybvx6pp/pRcUMKYghfHRTkUJ4mE5zr5FgQpkRHgW8njuQ7Ku6HpEnVZfoRKiDAr1GNYx7G0E y5DRRHnOQvRguNco+EYMi5IuJTPIeWgCYgkQKhr50LOioyuIYgGoHaYxqG15Rvpx1+S1/n6K AHwpEy4Hwip1ZqR872QJtFlV9MDhMmMkJMK1qSS2LiOiYN7N0rpdaddbEsRd6IgCglrP/9LU +ayaOpaL4DWk64HmBIMZSBLvXqMYYLCZVfDdkLpCEgI4OoTziBRyHp9+atHvK4s7KNCZZBYd xQLk8HzuumroqM4ExVYUuY+bpDXjkXSjgTSWb8UAdc4kIelb2o9D+AfIxp/DVShOquGgIqdv fnt9feHw2QgNS3n4nSX9Q2WYV59nXv05q43S+w1gMp20gm/4ulY9Nfm6M1zBdGP4jPl1evmF w8c5yvto5P5pd9zf3Fzd/jH+RGaAkDb1jLu/yGqDbwqAcc4IWLnu+l8ct+8/9iAaMH3Hazat PAFYmvnpBHSVOnIjCizqX3ViFISDgbFl4jovrfJA5krCMuJeqpdRmdFWGTJVnRbWT45XS4Q4 Omjti2YOfMt3nLcK25rv0d06Fn+6WRiWDMiH0ufoHgTjlC8a2CUmknLRdVTUFgZ+9Dll6KIh 6G7VtbDqaJM03JdLLuSrTvLlSq+3x9xQO0cDM3FirpyNubni7yx0omvOhNEgGbvrcDhrGkS8 w51BxFl5GCRnOnvN5VUwSG4do3h7ee3COOfk9tI1J7dTVz03X6Y6BhguLrX2xvHB2Ig4YiLH znEVJkKOEelqtaa1Q3BHPMVf8r1wdO6KB1/z4C88+JYHjx1NGU9dfRvzzuhIsszjm5Zz++mR jVkqGp3BocoGHejwQZTU9E5ogIM819AI/z2mzL3ayADT4+4xPnnMv8l2RHMv+i0JSHvLsxRx gC7InA7eU2RNXNvNFwPiaH7dlEvekwUp8DzuDtTl9vC6/TX6+fj01+71mbhOlfiCHZd3s8Sb V2ZKyrfD7vX0l/C9+vGyPT7bxnlCUl6KZzd6jvZAVBP0ACoUiSmN+Id5QgRnMX9PS4nQNcMl yCsS9PX6OiZnoggRneBVxipK+hOrl4JS0CyQM1gUU/r+hFol2iIuytzyXx4UTYzoptoSwjrg bhG6IHyap3+wf3kDGegPTOI6AsH76a+jmI0nCT9wcf9km+JsxrlVqEDfqNQAYQFyv1frIWoV RdpUtVRROYUDY22LQr6OLyZkPKq6jAtgl/hAwgoKME+hKN+rdK/HDFSWUAWaYF9gRKSqdaZl YBx0+k4QguKjUunWtHw1UVKVRskn9Wo24pVJIocqzxKqforuF3kXVs2oZZaXsKfWkSdCrKMF OlOPiImLQiK1CSXAXqqW8/H14oM84FA621dWawyKpUNyN+lRNQq339+fnzVGIMY32tQY59jI 4SjKQbxIY+maGxgOtG+jQV91eJvlbQWsTE/bYtBg5FFnX8ocQ7N1fo1GA6UOyAuxavYTj41K igYtarDSKE1g3uzSO4yzbfigtGybSgasM75ecTfufYxQRdMnM9E/5cHy1RN2OT0yJGoRzxfa awLpoGglqvazJF+bHzqQ4nPRWBwEa2f1QPfQLKThs9RscemNkv3TX+9vkpctHl+fqTtKHiyb QgX6p/EwMPyzE4lvUgZS2AycpRiQyKALD1PlELICbcP+CU278pImoi+sAy1pdeHwwHATq4KH XAoy+8EC7eZqjzrWdNyiR4kzL2/qr+PJBdeugfD3zTJo+1b1xa7vgE0Cswxz/p5GfgZcNc8L nrkTvNlpiey6Q2oVMVCdlzcSi8cgWUII666RNTq5faMsdB0dWP8yigr+ylPxSJAC06KXnnCR D6x29K/j2+4VLbOO/xm9vJ+2H1v4x/b09OeffxKvL8XpajiA62gTVdYmHWy9dIbQkxsNX68l DthfvsbXGGfzxVWwTFWs33uszt32IgYkiaE9ohgcZLstitbZgs6jKImiwuygakHrFXGfBrcy aoU9LXLK6v4mwwioz8jk47QLGZiQ44EPw4DuzFEUwuKQaUGZQ0GeOc7uwP8rfC6umCPBGTtZ LaXYdZuplsHcHB9xIx4bqdslKigjzDwGYoIdXrMMGk0cMOYd0XYb+HEGWsFzrQMaEfQTTi4E kgBTPdc48t1mn4wpvpsnrdzojrm/NbfAnZLJSksaMyjlcwiIQfh2ybWzG2WZlVh7nenGLeWJ iGYX1fgy+huqc88/Xpw4hBlESZmq28gUkXpLVJXuGm3eBCrO+1E3vhHRB7hPZripnA1mX9xM mmH/4QVj7XJqBR0lC+5503J8K6LlWDHahfwyazJZoyAqXdh56RULnqbTz2YGu2CQ7TquFzBo 88qsR6LTAFM7AEEgk0NQEryTFlsAKYWKYRYSqA9lKeTmWJQd6IdDiSxTxnpigWKZrNtqTQ0V sCQkYbw4ZQ/4C3WRtxcDcI8vb6fCy0+Jp8MmQy/JIna4Ypbvr0LPrbfHk8GMkmXIWq2IOGgi wHylzbmAV0bb/WGNwEHg1tZLHx/v3Hih9q0w5OFZMnmYXU/PJW2XHpPoBXltcU3Rh0W0CRvW 0Et2sRZzaWX+FcglYOt8Y0DFNcTMqsiP69Rz1tM01C5FgEpMSC/8rOxG84lcVNA6aTRifSQf Y5wNENcm1keajsRp2VFqDqvQFTMR5BudXcrGbTtReWiZzCYcGXSieaiZE+Hvc8pe44MOLPXg +EFwafq1IFt7sOkVIejMWeNwYRIU5xVLtP1q40rucpowIPLK5L67kmpoXgp0UFRSi1ABqO8H /Uq7M6Klhf6cW0dmje0m9AO92qLGtd6aL3kDyikOrckqD/MGFqW8qjNkJHxBS5pKN3KTdv91 yfuziZlGn1LH6YLuvbg0xfVie7G5uRg0FxMHEzDmcWp5T3hshiFHL2mTFRar41nUQOHwtuwp GteFZE+RaRFPh4dh0kRonS5HiQtPVB71N/fCbTaBQVlT3BKg38T6PZIsEyTY8t4EZmlMxXpt zSgBhL1+k95YyKItiyd6uQc6wBrNH8pOp6u2T++H3elv+yYc4yUTKXDIrQgIZNK65ZH6gDfZ ksYzUWiRDFW14QKzksscZ1SbVfZi6HNeCYNhOCGoWNkR0Nb0H6HZr7idXeT5kqu5o5xxVaqn YgaDaqchxQgj4gz62AiP9+JeCqyedaujEZFpgl2IFkBV3pRUHEPFU0QdjUrMoSFPxt+gZfs+ fT5+371+fj9uDy/7H9s/fm5/vW0Pn5hhglWT37O5IzsKr4DFn2q3VyaK3K9010dO0oUWMYrH 988TZ+iMpe4gAKkEhkc3tXORqkeSc2sFVHMvLOKMLU7h1C039zzWk957ejgM3KBzh0lmx6S4 CSEqn0HERygxyb5+enx7e4Q1cuhNGjY4nSh4k20hRTs91IaE4YUpXcoSuqGrRYKKOxMiJUWU /1cDSnCLPkxDcPj77bQfPWFOlf1hJFcx8f4TxLDZ5h6NVqKBJzY88kIWaJP6yTKICy3OqImx P9IXOAHapCU9GQYYS2jvia7pzpYsi4IF2kVglFXNsrert+JiryhkaHczChhg6mWwrewxVHCu XjMmFPshxmMSHN64PlNU89l4cpM2iYVAIZQF2oOFZ8BdEzWRhRF/7HWUOuBeUy8iGuWlg6PT hMnYFa6KU7ugObBX9QEKBt1O8d5PP7egcj49nrY/RtHrE+4cONRH/9udfo6843H/tBOo8PH0 aO2ggAaG7SpiYMHCg/8mF0We3I8vL67sJkd38YqZzwg+A0HIdrTxhXsvnlFHu1W+PV5BbY9T wEx+FPgWLCnXFqzgKtno50W3caJ7jApodWHxePzp6oEWi6hjBRxwI9th1rlKPdsNN9w9b48n u7IyuJwwIybA0j2FR/JQGJqE2z2ArMcXYTyzVwzL+ZxrJQ2nDOyKGYU0huWDgUAclisds0pD 2PFutoF4GrxwAE+urjnw5cSmrhbemANyRQD4amwPL4AvmV5WKRcpSSHreTm+ZfhTISuQp6WI eG6vQi+y9wfAtCwXBHx1Y/cE4VnsWERe1vgxU0UZTJlugmyxNkPWmjQY/i1J2LSmPQWadBjZ KgmOW0YI52wBu+Ms4nb9TPx1f7VceA+MPFF5SeVNLrhplhgc5jPdU4yWYbARU1lUFprXtg5v QQSesNNa04RUHWyd4/S44EwsUoPA6Fhv+3PYHo9wItGr0H7kZ3gtfm5FJA+cjqKQN1NOhkge OLvRAbngGO5DVYdW68vH1x/7l1H2/vJ9exjNt6/bw+OJ7wrGN2yDomSfF7vulj4qG1ljjbHA sOeDxHD8VWC4YxERFvBbXGOOafSIpmI7EbtaTpbuEHwTemzlEpd7Ck7i7ZFKMjfHdMHHfgIt IsXsSqAC4yUCXt3Y6257OGEcChB9jiKg6XH3/Pp4ej8oCzTNbEiahJNEr+q2gyiZJoVQVvFf Xz/1CpS4EliuiPSk7nTjByOL+wqTu7VaZp+Vme9N0mDG8Eql8T0Xg86PM69UN5N2vthk9/3w ePh7dNi/n3avVF6RuhjV0fy4LiMMoaddXw53xQOeewEVHaWWPp3ndFWXGSiM7azMU8M1ipIk UebAwmi1TR1TG/0OhX6heCcvXwBsPMbvi3PNjbVDOcFEae1uomd49IhU7EUS62sddOQgrjVG HIyvdQpbeIJ66qbVv7o0OBoKZNzbi0mSxEHk3/NCECGYMqV75drNhJHCj/lz0DzmA87VAVN5 WAJqQMzbvSaMaxIQctjnAiGGH9VUryfiH7yEfYNjtBQNnBeiqDKiUS4QGkY2/AGajrY3eEQZ UHVwDVBxrDBlA5wte/OAYPO3Uux0mIgJUNi0sRZ8VQE9mk1qgNWLJvUtRFXA4FpQP/hmwYzY p32H2vlDXLAIHxATFrN5sPcbc21aRmjRlCe5JulRKBZKN5kfLLQfwjya3OArjPbySZZhVeVB DPxLMLqSBmHFzQ+MQjdHRJBInqgxEPFipV/x4XtxludFmzvi1nVBeU2CbrcIF9sqnmeenikr vKN8Nsl9/RdjKZQlyiWrKzp5wCiTBJCXITUXDENCHZd3qNSRStMi1sIez3IUOs3XJYRWBtHN x40F0TOACuD1x5gLcy9wXz7GU6OMAt/nVNl6QR70LEOMq7Q0BjVn+nFtlAgNuLAKG198jG/Y qVQDkGFnXDUBejz5mGh8vkKbuIRlsxVGBcnJoPfnUYVrw4vJ7hAWJGFU0EDmlXwU12qTD+4c o/w/3JFHtWjCAQA= --/04w6evG8XlLl3ft-- From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751826AbdJRQCg (ORCPT ); Wed, 18 Oct 2017 12:02:36 -0400 Received: from mga05.intel.com ([192.55.52.43]:14140 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751728AbdJRQCe (ORCPT ); Wed, 18 Oct 2017 12:02:34 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,397,1503385200"; d="gz'50?scan'50,208,50";a="1026530360" Date: Thu, 19 Oct 2017 00:01:45 +0800 From: kbuild test robot To: changbin.du@intel.com Cc: kbuild-all@01.org, akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Changbin Du Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <201710182351.IgCZ78nr%fengguang.wu@intel.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="IJpNTDwzlM2Ie8A6" Content-Disposition: inline In-Reply-To: <1508145557-9944-2-git-send-email-changbin.du@intel.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --IJpNTDwzlM2Ie8A6 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Changbin, [auto build test ERROR on mmotm/master] [also build test ERROR on v4.14-rc5 next-20171017] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/changbin-du-intel-com/mm-thp-introduce-dedicated-transparent-huge-page-allocation-interfaces/20171018-230128 base: git://git.cmpxchg.org/linux-mmotm.git master config: i386-randconfig-x001-201742 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from include/linux/balloon_compaction.h:48:0, from drivers/virtio/virtio_balloon.c:29: include/linux/migrate.h: In function 'new_page_nodemask': >> include/linux/migrate.h:49:10: error: implicit declaration of function 'alloc_transhuge_page_nodemask' [-Werror=implicit-function-declaration] return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> include/linux/migrate.h:49:10: warning: return makes pointer from integer without a cast [-Wint-conversion] return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ preferred_nid, nodemask); ~~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +/alloc_transhuge_page_nodemask +49 include/linux/migrate.h 33 34 static inline struct page *new_page_nodemask(struct page *page, 35 int preferred_nid, nodemask_t *nodemask) 36 { 37 gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL; 38 unsigned int order = 0; 39 struct page *new_page = NULL; 40 41 if (PageHuge(page)) 42 return alloc_huge_page_nodemask(page_hstate(compound_head(page)), 43 preferred_nid, nodemask); 44 45 if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE)) 46 gfp_mask |= __GFP_HIGHMEM; 47 48 if (thp_migration_supported() && PageTransHuge(page)) > 49 return alloc_transhuge_page_nodemask(gfp_mask | GFP_TRANSHUGE, 50 preferred_nid, nodemask); 51 else 52 return __alloc_pages_nodemask(gfp_mask, order, 53 preferred_nid, nodemask); 54 55 return new_page; 56 } 57 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --IJpNTDwzlM2Ie8A6 Content-Type: application/gzip Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 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 --IJpNTDwzlM2Ie8A6-- From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753132AbdJSMtf (ORCPT ); Thu, 19 Oct 2017 08:49:35 -0400 Received: from mx2.suse.de ([195.135.220.15]:60481 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752277AbdJSMte (ORCPT ); Thu, 19 Oct 2017 08:49:34 -0400 Date: Thu, 19 Oct 2017 14:49:31 +0200 From: Michal Hocko To: "Du, Changbin" Cc: akpm@linux-foundation.org, corbet@lwn.net, hughd@google.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: Re: [PATCH 1/2] mm, thp: introduce dedicated transparent huge page allocation interfaces Message-ID: <20171019124931.p5zdvs2kdwu73mwh@dhcp22.suse.cz> References: <1508145557-9944-1-git-send-email-changbin.du@intel.com> <1508145557-9944-2-git-send-email-changbin.du@intel.com> <20171017102052.ltc2lb6r7kloazgs@dhcp22.suse.cz> <20171018110026.GA4352@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171018110026.GA4352@intel.com> User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed 18-10-17 19:00:26, Du, Changbin wrote: > Hi Hocko, > > On Tue, Oct 17, 2017 at 12:20:52PM +0200, Michal Hocko wrote: > > [CC Kirill] > > > > On Mon 16-10-17 17:19:16, changbin.du@intel.com wrote: > > > From: Changbin Du > > > > > > This patch introduced 4 new interfaces to allocate a prepared > > > transparent huge page. > > > - alloc_transhuge_page_vma > > > - alloc_transhuge_page_nodemask > > > - alloc_transhuge_page_node > > > - alloc_transhuge_page > > > > > > The aim is to remove duplicated code and simplify transparent > > > huge page allocation. These are similar to alloc_hugepage_xxx > > > which are for hugetlbfs pages. This patch does below changes: > > > - define alloc_transhuge_page_xxx interfaces > > > - apply them to all existing code > > > - declare prep_transhuge_page as static since no others use it > > > - remove alloc_hugepage_vma definition since it no longer has users > > > > So what exactly is the advantage of the new API? The diffstat doesn't > > sound very convincing to me. > > > The caller only need one step to allocate thp. Several LOCs removed for all the > caller side with this change. So it's little more convinent. Yeah, but the overall result is more code. So I am not really convinced. -- Michal Hocko SUSE Labs