Skip to content

Commit 9a76db0

Browse files
Lee Schermerhorntorvalds
authored andcommitted
hugetlb: rework hstate_next_node_* functions
Modify the hstate_next_node* functions to allow them to be called to obtain the "start_nid". Then, whereas prior to this patch we unconditionally called hstate_next_node_to_{alloc|free}(), whether or not we successfully allocated/freed a huge page on the node, now we only call these functions on failure to alloc/free to advance to next allowed node. Factor out the next_node_allowed() function to handle wrap at end of node_online_map. In this version, the allowed nodes include all of the online nodes. Signed-off-by: Lee Schermerhorn <[email protected]> Reviewed-by: Mel Gorman <[email protected]> Acked-by: David Rientjes <[email protected]> Reviewed-by: Andi Kleen <[email protected]> Cc: KAMEZAWA Hiroyuki <[email protected]> Cc: Randy Dunlap <[email protected]> Cc: Nishanth Aravamudan <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Adam Litke <[email protected]> Cc: Andy Whitcroft <[email protected]> Cc: Eric Whitney <[email protected]> Cc: Christoph Lameter <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 4e7b8a6 commit 9a76db0

File tree

1 file changed

+45
-25
lines changed

1 file changed

+45
-25
lines changed

mm/hugetlb.c

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,20 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid)
621621
return page;
622622
}
623623

624+
/*
625+
* common helper function for hstate_next_node_to_{alloc|free}.
626+
* return next node in node_online_map, wrapping at end.
627+
*/
628+
static int next_node_allowed(int nid)
629+
{
630+
nid = next_node(nid, node_online_map);
631+
if (nid == MAX_NUMNODES)
632+
nid = first_node(node_online_map);
633+
VM_BUG_ON(nid >= MAX_NUMNODES);
634+
635+
return nid;
636+
}
637+
624638
/*
625639
* Use a helper variable to find the next node and then
626640
* copy it back to next_nid_to_alloc afterwards:
@@ -634,12 +648,12 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid)
634648
*/
635649
static int hstate_next_node_to_alloc(struct hstate *h)
636650
{
637-
int next_nid;
638-
next_nid = next_node(h->next_nid_to_alloc, node_online_map);
639-
if (next_nid == MAX_NUMNODES)
640-
next_nid = first_node(node_online_map);
651+
int nid, next_nid;
652+
653+
nid = h->next_nid_to_alloc;
654+
next_nid = next_node_allowed(nid);
641655
h->next_nid_to_alloc = next_nid;
642-
return next_nid;
656+
return nid;
643657
}
644658

645659
static int alloc_fresh_huge_page(struct hstate *h)
@@ -649,15 +663,17 @@ static int alloc_fresh_huge_page(struct hstate *h)
649663
int next_nid;
650664
int ret = 0;
651665

652-
start_nid = h->next_nid_to_alloc;
666+
start_nid = hstate_next_node_to_alloc(h);
653667
next_nid = start_nid;
654668

655669
do {
656670
page = alloc_fresh_huge_page_node(h, next_nid);
657-
if (page)
671+
if (page) {
658672
ret = 1;
673+
break;
674+
}
659675
next_nid = hstate_next_node_to_alloc(h);
660-
} while (!page && next_nid != start_nid);
676+
} while (next_nid != start_nid);
661677

662678
if (ret)
663679
count_vm_event(HTLB_BUDDY_PGALLOC);
@@ -668,17 +684,19 @@ static int alloc_fresh_huge_page(struct hstate *h)
668684
}
669685

670686
/*
671-
* helper for free_pool_huge_page() - find next node
672-
* from which to free a huge page
687+
* helper for free_pool_huge_page() - return the next node
688+
* from which to free a huge page. Advance the next node id
689+
* whether or not we find a free huge page to free so that the
690+
* next attempt to free addresses the next node.
673691
*/
674692
static int hstate_next_node_to_free(struct hstate *h)
675693
{
676-
int next_nid;
677-
next_nid = next_node(h->next_nid_to_free, node_online_map);
678-
if (next_nid == MAX_NUMNODES)
679-
next_nid = first_node(node_online_map);
694+
int nid, next_nid;
695+
696+
nid = h->next_nid_to_free;
697+
next_nid = next_node_allowed(nid);
680698
h->next_nid_to_free = next_nid;
681-
return next_nid;
699+
return nid;
682700
}
683701

684702
/*
@@ -693,7 +711,7 @@ static int free_pool_huge_page(struct hstate *h, bool acct_surplus)
693711
int next_nid;
694712
int ret = 0;
695713

696-
start_nid = h->next_nid_to_free;
714+
start_nid = hstate_next_node_to_free(h);
697715
next_nid = start_nid;
698716

699717
do {
@@ -715,9 +733,10 @@ static int free_pool_huge_page(struct hstate *h, bool acct_surplus)
715733
}
716734
update_and_free_page(h, page);
717735
ret = 1;
736+
break;
718737
}
719738
next_nid = hstate_next_node_to_free(h);
720-
} while (!ret && next_nid != start_nid);
739+
} while (next_nid != start_nid);
721740

722741
return ret;
723742
}
@@ -1028,10 +1047,9 @@ int __weak alloc_bootmem_huge_page(struct hstate *h)
10281047
void *addr;
10291048

10301049
addr = __alloc_bootmem_node_nopanic(
1031-
NODE_DATA(h->next_nid_to_alloc),
1050+
NODE_DATA(hstate_next_node_to_alloc(h)),
10321051
huge_page_size(h), huge_page_size(h), 0);
10331052

1034-
hstate_next_node_to_alloc(h);
10351053
if (addr) {
10361054
/*
10371055
* Use the beginning of the huge page to store the
@@ -1167,29 +1185,31 @@ static int adjust_pool_surplus(struct hstate *h, int delta)
11671185
VM_BUG_ON(delta != -1 && delta != 1);
11681186

11691187
if (delta < 0)
1170-
start_nid = h->next_nid_to_alloc;
1188+
start_nid = hstate_next_node_to_alloc(h);
11711189
else
1172-
start_nid = h->next_nid_to_free;
1190+
start_nid = hstate_next_node_to_free(h);
11731191
next_nid = start_nid;
11741192

11751193
do {
11761194
int nid = next_nid;
11771195
if (delta < 0) {
1178-
next_nid = hstate_next_node_to_alloc(h);
11791196
/*
11801197
* To shrink on this node, there must be a surplus page
11811198
*/
1182-
if (!h->surplus_huge_pages_node[nid])
1199+
if (!h->surplus_huge_pages_node[nid]) {
1200+
next_nid = hstate_next_node_to_alloc(h);
11831201
continue;
1202+
}
11841203
}
11851204
if (delta > 0) {
1186-
next_nid = hstate_next_node_to_free(h);
11871205
/*
11881206
* Surplus cannot exceed the total number of pages
11891207
*/
11901208
if (h->surplus_huge_pages_node[nid] >=
1191-
h->nr_huge_pages_node[nid])
1209+
h->nr_huge_pages_node[nid]) {
1210+
next_nid = hstate_next_node_to_free(h);
11921211
continue;
1212+
}
11931213
}
11941214

11951215
h->surplus_huge_pages += delta;

0 commit comments

Comments
 (0)