diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/hugetlb.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 89e6286a7f57..20e04c64468d 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -296,8 +296,10 @@ static int gather_surplus_pages(int delta) | |||
296 | int needed, allocated; | 296 | int needed, allocated; |
297 | 297 | ||
298 | needed = (resv_huge_pages + delta) - free_huge_pages; | 298 | needed = (resv_huge_pages + delta) - free_huge_pages; |
299 | if (needed <= 0) | 299 | if (needed <= 0) { |
300 | resv_huge_pages += delta; | ||
300 | return 0; | 301 | return 0; |
302 | } | ||
301 | 303 | ||
302 | allocated = 0; | 304 | allocated = 0; |
303 | INIT_LIST_HEAD(&surplus_list); | 305 | INIT_LIST_HEAD(&surplus_list); |
@@ -335,9 +337,12 @@ retry: | |||
335 | * The surplus_list now contains _at_least_ the number of extra pages | 337 | * The surplus_list now contains _at_least_ the number of extra pages |
336 | * needed to accomodate the reservation. Add the appropriate number | 338 | * needed to accomodate the reservation. Add the appropriate number |
337 | * of pages to the hugetlb pool and free the extras back to the buddy | 339 | * of pages to the hugetlb pool and free the extras back to the buddy |
338 | * allocator. | 340 | * allocator. Commit the entire reservation here to prevent another |
341 | * process from stealing the pages as they are added to the pool but | ||
342 | * before they are reserved. | ||
339 | */ | 343 | */ |
340 | needed += allocated; | 344 | needed += allocated; |
345 | resv_huge_pages += delta; | ||
341 | ret = 0; | 346 | ret = 0; |
342 | free: | 347 | free: |
343 | list_for_each_entry_safe(page, tmp, &surplus_list, lru) { | 348 | list_for_each_entry_safe(page, tmp, &surplus_list, lru) { |
@@ -371,6 +376,9 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages) | |||
371 | struct page *page; | 376 | struct page *page; |
372 | unsigned long nr_pages; | 377 | unsigned long nr_pages; |
373 | 378 | ||
379 | /* Uncommit the reservation */ | ||
380 | resv_huge_pages -= unused_resv_pages; | ||
381 | |||
374 | nr_pages = min(unused_resv_pages, surplus_huge_pages); | 382 | nr_pages = min(unused_resv_pages, surplus_huge_pages); |
375 | 383 | ||
376 | while (nr_pages) { | 384 | while (nr_pages) { |
@@ -1205,12 +1213,13 @@ static int hugetlb_acct_memory(long delta) | |||
1205 | if (gather_surplus_pages(delta) < 0) | 1213 | if (gather_surplus_pages(delta) < 0) |
1206 | goto out; | 1214 | goto out; |
1207 | 1215 | ||
1208 | if (delta > cpuset_mems_nr(free_huge_pages_node)) | 1216 | if (delta > cpuset_mems_nr(free_huge_pages_node)) { |
1217 | return_unused_surplus_pages(delta); | ||
1209 | goto out; | 1218 | goto out; |
1219 | } | ||
1210 | } | 1220 | } |
1211 | 1221 | ||
1212 | ret = 0; | 1222 | ret = 0; |
1213 | resv_huge_pages += delta; | ||
1214 | if (delta < 0) | 1223 | if (delta < 0) |
1215 | return_unused_surplus_pages((unsigned long) -delta); | 1224 | return_unused_surplus_pages((unsigned long) -delta); |
1216 | 1225 | ||