diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/hugetlb.c | 27 | ||||
-rw-r--r-- | mm/memory_hotplug.c | 9 |
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)) |