diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 830c41a5ca70ea7cf67bac1f97a3a5c7fc5b7202..de6cdfa51694cb09b53fc91cd6e5136adfc80c2b 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -374,8 +374,15 @@ int huge_add_to_page_cache(struct page *page, struct address_space *mapping, pgoff_t idx); #ifdef CONFIG_ASCEND_FEATURES +#define HUGETLB_ALLOC_NONE 0x00 +#define HUGETLB_ALLOC_NORMAL 0x01 /* normal hugepage */ +#define HUGETLB_ALLOC_BUDDY 0x02 /* buddy hugepage */ +#define HUGETLB_ALLOC_MASK (HUGETLB_ALLOC_NONE | \ + HUGETLB_ALLOC_NORMAL | \ + HUGETLB_ALLOC_BUDDY) + const struct hstate *hugetlb_get_hstate(void); -struct page *hugetlb_alloc_hugepage(int nid); +struct page *hugetlb_alloc_hugepage(int nid, int flag); int hugetlb_insert_hugepage_pte(struct mm_struct *mm, unsigned long addr, pgprot_t prot, struct page *hpage); #else @@ -384,7 +391,7 @@ static inline const struct hstate *hugetlb_get_hstate(void) return NULL; } -static inline struct page *hugetlb_alloc_hugepage(int nid) +static inline struct page *hugetlb_alloc_hugepage(int nid, int flag) { return NULL; } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index b8874819a6aa905d4cd9e513863939dcc93eaf67..87f0f2bd6410b0f0c0dc95d49163ec0afa0f1918 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -5234,17 +5234,48 @@ const struct hstate *hugetlb_get_hstate(void) } EXPORT_SYMBOL_GPL(hugetlb_get_hstate); +static struct page *hugetlb_alloc_hugepage_normal(struct hstate *h, + gfp_t gfp_mask, int nid) +{ + struct page *page = NULL; + + spin_lock(&hugetlb_lock); + if (h->free_huge_pages - h->resv_huge_pages > 0) + page = dequeue_huge_page_nodemask(h, gfp_mask, nid, NULL, NULL); + spin_unlock(&hugetlb_lock); + + return page; +} + /* * Allocate hugepage without reserve */ -struct page *hugetlb_alloc_hugepage(int nid) +struct page *hugetlb_alloc_hugepage(int nid, int flag) { + struct hstate *h = &default_hstate; + gfp_t gfp_mask = htlb_alloc_mask(h); + struct page *page = NULL; + VM_WARN_ON(nid < 0 || nid >= MAX_NUMNODES); + if (flag & ~HUGETLB_ALLOC_MASK) + return NULL; + if (nid == NUMA_NO_NODE) nid = numa_mem_id(); - return alloc_huge_page_node(&default_hstate, nid); + gfp_mask |= __GFP_THISNODE; + + if (flag & HUGETLB_ALLOC_NORMAL) + page = hugetlb_alloc_hugepage_normal(h, gfp_mask, nid); + else if (flag & HUGETLB_ALLOC_BUDDY) { + if (enable_charge_mighp) + gfp_mask |= __GFP_ACCOUNT; + page = alloc_migrate_huge_page(h, gfp_mask, nid, NULL); + } else + page = alloc_huge_page_node(h, nid); + + return page; } EXPORT_SYMBOL_GPL(hugetlb_alloc_hugepage);