diff options
| -rw-r--r-- | mm/hugetlb.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index dcacc811e70e..74c1b6b0b37b 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
| @@ -286,6 +286,12 @@ static struct page *alloc_buddy_huge_page(struct vm_area_struct *vma, | |||
| 286 | 286 | ||
| 287 | spin_lock(&hugetlb_lock); | 287 | spin_lock(&hugetlb_lock); |
| 288 | if (page) { | 288 | if (page) { |
| 289 | /* | ||
| 290 | * This page is now managed by the hugetlb allocator and has | ||
| 291 | * no users -- drop the buddy allocator's reference. | ||
| 292 | */ | ||
| 293 | put_page_testzero(page); | ||
| 294 | VM_BUG_ON(page_count(page)); | ||
| 289 | nid = page_to_nid(page); | 295 | nid = page_to_nid(page); |
| 290 | set_compound_page_dtor(page, free_huge_page); | 296 | set_compound_page_dtor(page, free_huge_page); |
| 291 | /* | 297 | /* |
| @@ -369,13 +375,14 @@ free: | |||
| 369 | enqueue_huge_page(page); | 375 | enqueue_huge_page(page); |
| 370 | else { | 376 | else { |
| 371 | /* | 377 | /* |
| 372 | * Decrement the refcount and free the page using its | 378 | * The page has a reference count of zero already, so |
| 373 | * destructor. This must be done with hugetlb_lock | 379 | * call free_huge_page directly instead of using |
| 380 | * put_page. This must be done with hugetlb_lock | ||
| 374 | * unlocked which is safe because free_huge_page takes | 381 | * unlocked which is safe because free_huge_page takes |
| 375 | * hugetlb_lock before deciding how to free the page. | 382 | * hugetlb_lock before deciding how to free the page. |
| 376 | */ | 383 | */ |
| 377 | spin_unlock(&hugetlb_lock); | 384 | spin_unlock(&hugetlb_lock); |
| 378 | put_page(page); | 385 | free_huge_page(page); |
| 379 | spin_lock(&hugetlb_lock); | 386 | spin_lock(&hugetlb_lock); |
| 380 | } | 387 | } |
| 381 | } | 388 | } |
