diff options
Diffstat (limited to 'mm')
-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 7224a4f07106..e0fda156f021 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -418,9 +418,14 @@ static struct page *alloc_huge_page_private(struct vm_area_struct *vma, | |||
418 | if (free_huge_pages > resv_huge_pages) | 418 | if (free_huge_pages > resv_huge_pages) |
419 | page = dequeue_huge_page(vma, addr); | 419 | page = dequeue_huge_page(vma, addr); |
420 | spin_unlock(&hugetlb_lock); | 420 | spin_unlock(&hugetlb_lock); |
421 | if (!page) | 421 | if (!page) { |
422 | page = alloc_buddy_huge_page(vma, addr); | 422 | page = alloc_buddy_huge_page(vma, addr); |
423 | return page ? page : ERR_PTR(-VM_FAULT_OOM); | 423 | if (!page) { |
424 | hugetlb_put_quota(vma->vm_file->f_mapping, 1); | ||
425 | return ERR_PTR(-VM_FAULT_OOM); | ||
426 | } | ||
427 | } | ||
428 | return page; | ||
424 | } | 429 | } |
425 | 430 | ||
426 | static struct page *alloc_huge_page(struct vm_area_struct *vma, | 431 | static struct page *alloc_huge_page(struct vm_area_struct *vma, |
@@ -1206,8 +1211,10 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to) | |||
1206 | if (hugetlb_get_quota(inode->i_mapping, chg)) | 1211 | if (hugetlb_get_quota(inode->i_mapping, chg)) |
1207 | return -ENOSPC; | 1212 | return -ENOSPC; |
1208 | ret = hugetlb_acct_memory(chg); | 1213 | ret = hugetlb_acct_memory(chg); |
1209 | if (ret < 0) | 1214 | if (ret < 0) { |
1215 | hugetlb_put_quota(inode->i_mapping, chg); | ||
1210 | return ret; | 1216 | return ret; |
1217 | } | ||
1211 | region_add(&inode->i_mapping->private_list, from, to); | 1218 | region_add(&inode->i_mapping->private_list, from, to); |
1212 | return 0; | 1219 | return 0; |
1213 | } | 1220 | } |