summaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/hugetlb.c27
-rw-r--r--mm/memory_hotplug.c9
2 files changed, 29 insertions, 7 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 761a669d0b62..01c11ceb47d6 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1723,6 +1723,33 @@ struct page *alloc_huge_page_node(struct hstate *h, int nid)
return page;
}
+struct page *alloc_huge_page_nodemask(struct hstate *h, const nodemask_t *nmask)
+{
+ struct page *page = NULL;
+ int node;
+
+ spin_lock(&hugetlb_lock);
+ if (h->free_huge_pages - h->resv_huge_pages > 0) {
+ for_each_node_mask(node, *nmask) {
+ page = dequeue_huge_page_node_exact(h, node);
+ if (page)
+ break;
+ }
+ }
+ spin_unlock(&hugetlb_lock);
+ if (page)
+ return page;
+
+ /* No reservations, try to overcommit */
+ for_each_node_mask(node, *nmask) {
+ page = __alloc_buddy_huge_page_no_mpol(h, node);
+ if (page)
+ return page;
+ }
+
+ return NULL;
+}
+
/*
* Increase the hugetlb pool such that it can accommodate a reservation
* of size 'delta'.
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index f42a8ef93ec4..1cf3404bd065 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1446,14 +1446,9 @@ static struct page *new_node_page(struct page *page, unsigned long private,
if (nodes_empty(nmask))
node_set(nid, nmask);
- /*
- * TODO: allocate a destination hugepage from a nearest neighbor node,
- * accordance with memory policy of the user process if possible. For
- * now as a simple work-around, we use the next node for destination.
- */
if (PageHuge(page))
- return alloc_huge_page_node(page_hstate(compound_head(page)),
- next_node_in(nid, nmask));
+ return alloc_huge_page_nodemask(
+ page_hstate(compound_head(page)), &nmask);
if (PageHighMem(page)
|| (zone_idx(page_zone(page)) == ZONE_MOVABLE))