Skip to content

Commit 0c397da

Browse files
Michal Hockotorvalds
authored andcommitted
mm, hugetlb: further simplify hugetlb allocation API
Hugetlb allocator has several layer of allocation functions depending and the purpose of the allocation. There are two allocators depending on whether the page can be allocated from the page allocator or we need a contiguous allocator. This is currently opencoded in alloc_fresh_huge_page which is the only path that might allocate giga pages which require the later allocator. Create alloc_fresh_huge_page which hides this implementation detail and use it in all callers which hardcoded the buddy allocator path (__hugetlb_alloc_buddy_huge_page). This shouldn't introduce any funtional change because both migration and surplus allocators exlude giga pages explicitly. While we are at it let's do some renaming. The current scheme is not consistent and overly painfull to read and understand. Get rid of prefix underscores from most functions. There is no real reason to make names longer. * alloc_fresh_huge_page is the new layer to abstract underlying allocator * __hugetlb_alloc_buddy_huge_page becomes shorter and neater alloc_buddy_huge_page. * Former alloc_fresh_huge_page becomes alloc_pool_huge_page because we put the new page directly to the pool * alloc_surplus_huge_page can drop the opencoded prep_new_huge_page code as it uses alloc_fresh_huge_page now * others lose their excessive prefix underscores to make names shorter [dan.carpenter@oracle.com: fix double unlock bug in alloc_surplus_huge_page()] Link: http://lkml.kernel.org/r/20180109200559.g3iz5kvbdrz7yydp@mwanda Link: http://lkml.kernel.org/r/20180103093213.26329-6-mhocko@kernel.org Signed-off-by: Michal Hocko <mhocko@suse.com> Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com> Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Cc: Andrea Reale <ar@linux.vnet.ibm.com> Cc: Anshuman Khandual <khandual@linux.vnet.ibm.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Zi Yan <zi.yan@cs.rutgers.edu> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 9980d74 commit 0c397da

File tree

1 file changed

+43
-37
lines changed

1 file changed

+43
-37
lines changed

mm/hugetlb.c

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,7 +1378,7 @@ pgoff_t __basepage_index(struct page *page)
13781378
return (index << compound_order(page_head)) + compound_idx;
13791379
}
13801380

1381-
static struct page *__hugetlb_alloc_buddy_huge_page(struct hstate *h,
1381+
static struct page *alloc_buddy_huge_page(struct hstate *h,
13821382
gfp_t gfp_mask, int nid, nodemask_t *nmask)
13831383
{
13841384
int order = huge_page_order(h);
@@ -1396,34 +1396,49 @@ static struct page *__hugetlb_alloc_buddy_huge_page(struct hstate *h,
13961396
return page;
13971397
}
13981398

1399+
/*
1400+
* Common helper to allocate a fresh hugetlb page. All specific allocators
1401+
* should use this function to get new hugetlb pages
1402+
*/
1403+
static struct page *alloc_fresh_huge_page(struct hstate *h,
1404+
gfp_t gfp_mask, int nid, nodemask_t *nmask)
1405+
{
1406+
struct page *page;
1407+
1408+
if (hstate_is_gigantic(h))
1409+
page = alloc_gigantic_page(h, gfp_mask, nid, nmask);
1410+
else
1411+
page = alloc_buddy_huge_page(h, gfp_mask,
1412+
nid, nmask);
1413+
if (!page)
1414+
return NULL;
1415+
1416+
if (hstate_is_gigantic(h))
1417+
prep_compound_gigantic_page(page, huge_page_order(h));
1418+
prep_new_huge_page(h, page, page_to_nid(page));
1419+
1420+
return page;
1421+
}
1422+
13991423
/*
14001424
* Allocates a fresh page to the hugetlb allocator pool in the node interleaved
14011425
* manner.
14021426
*/
1403-
static int alloc_fresh_huge_page(struct hstate *h, nodemask_t *nodes_allowed)
1427+
static int alloc_pool_huge_page(struct hstate *h, nodemask_t *nodes_allowed)
14041428
{
14051429
struct page *page;
14061430
int nr_nodes, node;
14071431
gfp_t gfp_mask = htlb_alloc_mask(h) | __GFP_THISNODE;
14081432

14091433
for_each_node_mask_to_alloc(h, nr_nodes, node, nodes_allowed) {
1410-
if (hstate_is_gigantic(h))
1411-
page = alloc_gigantic_page(h, gfp_mask,
1412-
node, nodes_allowed);
1413-
else
1414-
page = __hugetlb_alloc_buddy_huge_page(h, gfp_mask,
1415-
node, nodes_allowed);
1434+
page = alloc_fresh_huge_page(h, gfp_mask, node, nodes_allowed);
14161435
if (page)
14171436
break;
1418-
14191437
}
14201438

14211439
if (!page)
14221440
return 0;
14231441

1424-
if (hstate_is_gigantic(h))
1425-
prep_compound_gigantic_page(page, huge_page_order(h));
1426-
prep_new_huge_page(h, page, page_to_nid(page));
14271442
put_page(page); /* free it into the hugepage allocator */
14281443

14291444
return 1;
@@ -1537,7 +1552,7 @@ int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
15371552
/*
15381553
* Allocates a fresh surplus page from the page allocator.
15391554
*/
1540-
static struct page *__alloc_surplus_huge_page(struct hstate *h, gfp_t gfp_mask,
1555+
static struct page *alloc_surplus_huge_page(struct hstate *h, gfp_t gfp_mask,
15411556
int nid, nodemask_t *nmask)
15421557
{
15431558
struct page *page = NULL;
@@ -1550,9 +1565,9 @@ static struct page *__alloc_surplus_huge_page(struct hstate *h, gfp_t gfp_mask,
15501565
goto out_unlock;
15511566
spin_unlock(&hugetlb_lock);
15521567

1553-
page = __hugetlb_alloc_buddy_huge_page(h, gfp_mask, nid, nmask);
1568+
page = alloc_fresh_huge_page(h, gfp_mask, nid, nmask);
15541569
if (!page)
1555-
goto out_unlock;
1570+
return NULL;
15561571

15571572
spin_lock(&hugetlb_lock);
15581573
/*
@@ -1567,16 +1582,8 @@ static struct page *__alloc_surplus_huge_page(struct hstate *h, gfp_t gfp_mask,
15671582
put_page(page);
15681583
page = NULL;
15691584
} else {
1570-
int r_nid;
1571-
15721585
h->surplus_huge_pages++;
1573-
h->nr_huge_pages++;
1574-
INIT_LIST_HEAD(&page->lru);
1575-
r_nid = page_to_nid(page);
1576-
set_compound_page_dtor(page, HUGETLB_PAGE_DTOR);
1577-
set_hugetlb_cgroup(page, NULL);
1578-
h->nr_huge_pages_node[r_nid]++;
1579-
h->surplus_huge_pages_node[r_nid]++;
1586+
h->nr_huge_pages_node[page_to_nid(page)]++;
15801587
}
15811588

15821589
out_unlock:
@@ -1585,23 +1592,22 @@ static struct page *__alloc_surplus_huge_page(struct hstate *h, gfp_t gfp_mask,
15851592
return page;
15861593
}
15871594

1588-
static struct page *__alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
1595+
static struct page *alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
15891596
int nid, nodemask_t *nmask)
15901597
{
15911598
struct page *page;
15921599

15931600
if (hstate_is_gigantic(h))
15941601
return NULL;
15951602

1596-
page = __hugetlb_alloc_buddy_huge_page(h, gfp_mask, nid, nmask);
1603+
page = alloc_fresh_huge_page(h, gfp_mask, nid, nmask);
15971604
if (!page)
15981605
return NULL;
15991606

16001607
/*
16011608
* We do not account these pages as surplus because they are only
16021609
* temporary and will be released properly on the last reference
16031610
*/
1604-
prep_new_huge_page(h, page, page_to_nid(page));
16051611
SetPageHugeTemporary(page);
16061612

16071613
return page;
@@ -1611,7 +1617,7 @@ static struct page *__alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
16111617
* Use the VMA's mpolicy to allocate a huge page from the buddy.
16121618
*/
16131619
static
1614-
struct page *__alloc_buddy_huge_page_with_mpol(struct hstate *h,
1620+
struct page *alloc_buddy_huge_page_with_mpol(struct hstate *h,
16151621
struct vm_area_struct *vma, unsigned long addr)
16161622
{
16171623
struct page *page;
@@ -1621,7 +1627,7 @@ struct page *__alloc_buddy_huge_page_with_mpol(struct hstate *h,
16211627
nodemask_t *nodemask;
16221628

16231629
nid = huge_node(vma, addr, gfp_mask, &mpol, &nodemask);
1624-
page = __alloc_surplus_huge_page(h, gfp_mask, nid, nodemask);
1630+
page = alloc_surplus_huge_page(h, gfp_mask, nid, nodemask);
16251631
mpol_cond_put(mpol);
16261632

16271633
return page;
@@ -1642,7 +1648,7 @@ struct page *alloc_huge_page_node(struct hstate *h, int nid)
16421648
spin_unlock(&hugetlb_lock);
16431649

16441650
if (!page)
1645-
page = __alloc_migrate_huge_page(h, gfp_mask, nid, NULL);
1651+
page = alloc_migrate_huge_page(h, gfp_mask, nid, NULL);
16461652

16471653
return page;
16481654
}
@@ -1665,7 +1671,7 @@ struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid,
16651671
}
16661672
spin_unlock(&hugetlb_lock);
16671673

1668-
return __alloc_migrate_huge_page(h, gfp_mask, preferred_nid, nmask);
1674+
return alloc_migrate_huge_page(h, gfp_mask, preferred_nid, nmask);
16691675
}
16701676

16711677
/*
@@ -1693,7 +1699,7 @@ static int gather_surplus_pages(struct hstate *h, int delta)
16931699
retry:
16941700
spin_unlock(&hugetlb_lock);
16951701
for (i = 0; i < needed; i++) {
1696-
page = __alloc_surplus_huge_page(h, htlb_alloc_mask(h),
1702+
page = alloc_surplus_huge_page(h, htlb_alloc_mask(h),
16971703
NUMA_NO_NODE, NULL);
16981704
if (!page) {
16991705
alloc_ok = false;
@@ -2030,7 +2036,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
20302036
page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve, gbl_chg);
20312037
if (!page) {
20322038
spin_unlock(&hugetlb_lock);
2033-
page = __alloc_buddy_huge_page_with_mpol(h, vma, addr);
2039+
page = alloc_buddy_huge_page_with_mpol(h, vma, addr);
20342040
if (!page)
20352041
goto out_uncharge_cgroup;
20362042
if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) {
@@ -2170,7 +2176,7 @@ static void __init hugetlb_hstate_alloc_pages(struct hstate *h)
21702176
if (hstate_is_gigantic(h)) {
21712177
if (!alloc_bootmem_huge_page(h))
21722178
break;
2173-
} else if (!alloc_fresh_huge_page(h,
2179+
} else if (!alloc_pool_huge_page(h,
21742180
&node_states[N_MEMORY]))
21752181
break;
21762182
cond_resched();
@@ -2290,7 +2296,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
22902296
* First take pages out of surplus state. Then make up the
22912297
* remaining difference by allocating fresh huge pages.
22922298
*
2293-
* We might race with __alloc_surplus_huge_page() here and be unable
2299+
* We might race with alloc_surplus_huge_page() here and be unable
22942300
* to convert a surplus huge page to a normal huge page. That is
22952301
* not critical, though, it just means the overall size of the
22962302
* pool might be one hugepage larger than it needs to be, but
@@ -2313,7 +2319,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
23132319
/* yield cpu to avoid soft lockup */
23142320
cond_resched();
23152321

2316-
ret = alloc_fresh_huge_page(h, nodes_allowed);
2322+
ret = alloc_pool_huge_page(h, nodes_allowed);
23172323
spin_lock(&hugetlb_lock);
23182324
if (!ret)
23192325
goto out;
@@ -2333,7 +2339,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
23332339
* By placing pages into the surplus state independent of the
23342340
* overcommit value, we are allowing the surplus pool size to
23352341
* exceed overcommit. There are few sane options here. Since
2336-
* __alloc_surplus_huge_page() is checking the global counter,
2342+
* alloc_surplus_huge_page() is checking the global counter,
23372343
* though, we'll note that we're not allowed to exceed surplus
23382344
* and won't grow the pool anywhere else. Not until one of the
23392345
* sysctls are changed, or the surplus pages go out of use.

0 commit comments

Comments
 (0)