diff options
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r-- | mm/hugetlb.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 40d841cb5126..51c9e2c01640 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -401,12 +401,20 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages) | |||
401 | struct page *page; | 401 | struct page *page; |
402 | unsigned long nr_pages; | 402 | unsigned long nr_pages; |
403 | 403 | ||
404 | /* | ||
405 | * We want to release as many surplus pages as possible, spread | ||
406 | * evenly across all nodes. Iterate across all nodes until we | ||
407 | * can no longer free unreserved surplus pages. This occurs when | ||
408 | * the nodes with surplus pages have no free pages. | ||
409 | */ | ||
410 | unsigned long remaining_iterations = num_online_nodes(); | ||
411 | |||
404 | /* Uncommit the reservation */ | 412 | /* Uncommit the reservation */ |
405 | resv_huge_pages -= unused_resv_pages; | 413 | resv_huge_pages -= unused_resv_pages; |
406 | 414 | ||
407 | nr_pages = min(unused_resv_pages, surplus_huge_pages); | 415 | nr_pages = min(unused_resv_pages, surplus_huge_pages); |
408 | 416 | ||
409 | while (nr_pages) { | 417 | while (remaining_iterations-- && nr_pages) { |
410 | nid = next_node(nid, node_online_map); | 418 | nid = next_node(nid, node_online_map); |
411 | if (nid == MAX_NUMNODES) | 419 | if (nid == MAX_NUMNODES) |
412 | nid = first_node(node_online_map); | 420 | nid = first_node(node_online_map); |
@@ -424,6 +432,7 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages) | |||
424 | surplus_huge_pages--; | 432 | surplus_huge_pages--; |
425 | surplus_huge_pages_node[nid]--; | 433 | surplus_huge_pages_node[nid]--; |
426 | nr_pages--; | 434 | nr_pages--; |
435 | remaining_iterations = num_online_nodes(); | ||
427 | } | 436 | } |
428 | } | 437 | } |
429 | } | 438 | } |