aboutsummaryrefslogtreecommitdiffstats
path: root/mm/hugetlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r--mm/hugetlb.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 89e6286a7f57..dcacc811e70e 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -71,7 +71,25 @@ static void enqueue_huge_page(struct page *page)
71 free_huge_pages_node[nid]++; 71 free_huge_pages_node[nid]++;
72} 72}
73 73
74static struct page *dequeue_huge_page(struct vm_area_struct *vma, 74static struct page *dequeue_huge_page(void)
75{
76 int nid;
77 struct page *page = NULL;
78
79 for (nid = 0; nid < MAX_NUMNODES; ++nid) {
80 if (!list_empty(&hugepage_freelists[nid])) {
81 page = list_entry(hugepage_freelists[nid].next,
82 struct page, lru);
83 list_del(&page->lru);
84 free_huge_pages--;
85 free_huge_pages_node[nid]--;
86 break;
87 }
88 }
89 return page;
90}
91
92static struct page *dequeue_huge_page_vma(struct vm_area_struct *vma,
75 unsigned long address) 93 unsigned long address)
76{ 94{
77 int nid; 95 int nid;
@@ -296,8 +314,10 @@ static int gather_surplus_pages(int delta)
296 int needed, allocated; 314 int needed, allocated;
297 315
298 needed = (resv_huge_pages + delta) - free_huge_pages; 316 needed = (resv_huge_pages + delta) - free_huge_pages;
299 if (needed <= 0) 317 if (needed <= 0) {
318 resv_huge_pages += delta;
300 return 0; 319 return 0;
320 }
301 321
302 allocated = 0; 322 allocated = 0;
303 INIT_LIST_HEAD(&surplus_list); 323 INIT_LIST_HEAD(&surplus_list);
@@ -335,9 +355,12 @@ retry:
335 * The surplus_list now contains _at_least_ the number of extra pages 355 * The surplus_list now contains _at_least_ the number of extra pages
336 * needed to accomodate the reservation. Add the appropriate number 356 * needed to accomodate the reservation. Add the appropriate number
337 * of pages to the hugetlb pool and free the extras back to the buddy 357 * of pages to the hugetlb pool and free the extras back to the buddy
338 * allocator. 358 * allocator. Commit the entire reservation here to prevent another
359 * process from stealing the pages as they are added to the pool but
360 * before they are reserved.
339 */ 361 */
340 needed += allocated; 362 needed += allocated;
363 resv_huge_pages += delta;
341 ret = 0; 364 ret = 0;
342free: 365free:
343 list_for_each_entry_safe(page, tmp, &surplus_list, lru) { 366 list_for_each_entry_safe(page, tmp, &surplus_list, lru) {
@@ -371,6 +394,9 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages)
371 struct page *page; 394 struct page *page;
372 unsigned long nr_pages; 395 unsigned long nr_pages;
373 396
397 /* Uncommit the reservation */
398 resv_huge_pages -= unused_resv_pages;
399
374 nr_pages = min(unused_resv_pages, surplus_huge_pages); 400 nr_pages = min(unused_resv_pages, surplus_huge_pages);
375 401
376 while (nr_pages) { 402 while (nr_pages) {
@@ -402,7 +428,7 @@ static struct page *alloc_huge_page_shared(struct vm_area_struct *vma,
402 struct page *page; 428 struct page *page;
403 429
404 spin_lock(&hugetlb_lock); 430 spin_lock(&hugetlb_lock);
405 page = dequeue_huge_page(vma, addr); 431 page = dequeue_huge_page_vma(vma, addr);
406 spin_unlock(&hugetlb_lock); 432 spin_unlock(&hugetlb_lock);
407 return page ? page : ERR_PTR(-VM_FAULT_OOM); 433 return page ? page : ERR_PTR(-VM_FAULT_OOM);
408} 434}
@@ -417,7 +443,7 @@ static struct page *alloc_huge_page_private(struct vm_area_struct *vma,
417 443
418 spin_lock(&hugetlb_lock); 444 spin_lock(&hugetlb_lock);
419 if (free_huge_pages > resv_huge_pages) 445 if (free_huge_pages > resv_huge_pages)
420 page = dequeue_huge_page(vma, addr); 446 page = dequeue_huge_page_vma(vma, addr);
421 spin_unlock(&hugetlb_lock); 447 spin_unlock(&hugetlb_lock);
422 if (!page) { 448 if (!page) {
423 page = alloc_buddy_huge_page(vma, addr); 449 page = alloc_buddy_huge_page(vma, addr);
@@ -570,7 +596,7 @@ static unsigned long set_max_huge_pages(unsigned long count)
570 min_count = max(count, min_count); 596 min_count = max(count, min_count);
571 try_to_free_low(min_count); 597 try_to_free_low(min_count);
572 while (min_count < persistent_huge_pages) { 598 while (min_count < persistent_huge_pages) {
573 struct page *page = dequeue_huge_page(NULL, 0); 599 struct page *page = dequeue_huge_page();
574 if (!page) 600 if (!page)
575 break; 601 break;
576 update_and_free_page(page); 602 update_and_free_page(page);
@@ -1205,12 +1231,13 @@ static int hugetlb_acct_memory(long delta)
1205 if (gather_surplus_pages(delta) < 0) 1231 if (gather_surplus_pages(delta) < 0)
1206 goto out; 1232 goto out;
1207 1233
1208 if (delta > cpuset_mems_nr(free_huge_pages_node)) 1234 if (delta > cpuset_mems_nr(free_huge_pages_node)) {
1235 return_unused_surplus_pages(delta);
1209 goto out; 1236 goto out;
1237 }
1210 } 1238 }
1211 1239
1212 ret = 0; 1240 ret = 0;
1213 resv_huge_pages += delta;
1214 if (delta < 0) 1241 if (delta < 0)
1215 return_unused_surplus_pages((unsigned long) -delta); 1242 return_unused_surplus_pages((unsigned long) -delta);
1216 1243