aboutsummaryrefslogtreecommitdiffstats
path: root/mm/hugetlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r--mm/hugetlb.c95
1 files changed, 62 insertions, 33 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 8b809ecefa39..6121b57bbe96 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -116,7 +116,9 @@ static void update_and_free_page(struct page *page)
116static void free_huge_page(struct page *page) 116static void free_huge_page(struct page *page)
117{ 117{
118 int nid = page_to_nid(page); 118 int nid = page_to_nid(page);
119 struct address_space *mapping;
119 120
121 mapping = (struct address_space *) page_private(page);
120 BUG_ON(page_count(page)); 122 BUG_ON(page_count(page));
121 INIT_LIST_HEAD(&page->lru); 123 INIT_LIST_HEAD(&page->lru);
122 124
@@ -129,6 +131,9 @@ static void free_huge_page(struct page *page)
129 enqueue_huge_page(page); 131 enqueue_huge_page(page);
130 } 132 }
131 spin_unlock(&hugetlb_lock); 133 spin_unlock(&hugetlb_lock);
134 if (mapping)
135 hugetlb_put_quota(mapping, 1);
136 set_page_private(page, 0);
132} 137}
133 138
134/* 139/*
@@ -323,7 +328,7 @@ free:
323 * allocated to satisfy the reservation must be explicitly freed if they were 328 * allocated to satisfy the reservation must be explicitly freed if they were
324 * never used. 329 * never used.
325 */ 330 */
326void return_unused_surplus_pages(unsigned long unused_resv_pages) 331static void return_unused_surplus_pages(unsigned long unused_resv_pages)
327{ 332{
328 static int nid = -1; 333 static int nid = -1;
329 struct page *page; 334 struct page *page;
@@ -353,35 +358,50 @@ void return_unused_surplus_pages(unsigned long unused_resv_pages)
353 } 358 }
354} 359}
355 360
356static struct page *alloc_huge_page(struct vm_area_struct *vma, 361
357 unsigned long addr) 362static struct page *alloc_huge_page_shared(struct vm_area_struct *vma,
363 unsigned long addr)
358{ 364{
359 struct page *page = NULL; 365 struct page *page;
360 int use_reserved_page = vma->vm_flags & VM_MAYSHARE;
361 366
362 spin_lock(&hugetlb_lock); 367 spin_lock(&hugetlb_lock);
363 if (!use_reserved_page && (free_huge_pages <= resv_huge_pages))
364 goto fail;
365
366 page = dequeue_huge_page(vma, addr); 368 page = dequeue_huge_page(vma, addr);
367 if (!page)
368 goto fail;
369
370 spin_unlock(&hugetlb_lock); 369 spin_unlock(&hugetlb_lock);
371 set_page_refcounted(page); 370 return page ? page : ERR_PTR(-VM_FAULT_OOM);
372 return page; 371}
373 372
374fail: 373static struct page *alloc_huge_page_private(struct vm_area_struct *vma,
375 spin_unlock(&hugetlb_lock); 374 unsigned long addr)
375{
376 struct page *page = NULL;
376 377
377 /* 378 if (hugetlb_get_quota(vma->vm_file->f_mapping, 1))
378 * Private mappings do not use reserved huge pages so the allocation 379 return ERR_PTR(-VM_FAULT_SIGBUS);
379 * may have failed due to an undersized hugetlb pool. Try to grab a 380
380 * surplus huge page from the buddy allocator. 381 spin_lock(&hugetlb_lock);
381 */ 382 if (free_huge_pages > resv_huge_pages)
382 if (!use_reserved_page) 383 page = dequeue_huge_page(vma, addr);
384 spin_unlock(&hugetlb_lock);
385 if (!page)
383 page = alloc_buddy_huge_page(vma, addr); 386 page = alloc_buddy_huge_page(vma, addr);
387 return page ? page : ERR_PTR(-VM_FAULT_OOM);
388}
389
390static struct page *alloc_huge_page(struct vm_area_struct *vma,
391 unsigned long addr)
392{
393 struct page *page;
394 struct address_space *mapping = vma->vm_file->f_mapping;
384 395
396 if (vma->vm_flags & VM_MAYSHARE)
397 page = alloc_huge_page_shared(vma, addr);
398 else
399 page = alloc_huge_page_private(vma, addr);
400
401 if (!IS_ERR(page)) {
402 set_page_refcounted(page);
403 set_page_private(page, (unsigned long) mapping);
404 }
385 return page; 405 return page;
386} 406}
387 407
@@ -726,9 +746,9 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
726 page_cache_get(old_page); 746 page_cache_get(old_page);
727 new_page = alloc_huge_page(vma, address); 747 new_page = alloc_huge_page(vma, address);
728 748
729 if (!new_page) { 749 if (IS_ERR(new_page)) {
730 page_cache_release(old_page); 750 page_cache_release(old_page);
731 return VM_FAULT_OOM; 751 return -PTR_ERR(new_page);
732 } 752 }
733 753
734 spin_unlock(&mm->page_table_lock); 754 spin_unlock(&mm->page_table_lock);
@@ -772,27 +792,28 @@ retry:
772 size = i_size_read(mapping->host) >> HPAGE_SHIFT; 792 size = i_size_read(mapping->host) >> HPAGE_SHIFT;
773 if (idx >= size) 793 if (idx >= size)
774 goto out; 794 goto out;
775 if (hugetlb_get_quota(mapping))
776 goto out;
777 page = alloc_huge_page(vma, address); 795 page = alloc_huge_page(vma, address);
778 if (!page) { 796 if (IS_ERR(page)) {
779 hugetlb_put_quota(mapping); 797 ret = -PTR_ERR(page);
780 ret = VM_FAULT_OOM;
781 goto out; 798 goto out;
782 } 799 }
783 clear_huge_page(page, address); 800 clear_huge_page(page, address);
784 801
785 if (vma->vm_flags & VM_SHARED) { 802 if (vma->vm_flags & VM_SHARED) {
786 int err; 803 int err;
804 struct inode *inode = mapping->host;
787 805
788 err = add_to_page_cache(page, mapping, idx, GFP_KERNEL); 806 err = add_to_page_cache(page, mapping, idx, GFP_KERNEL);
789 if (err) { 807 if (err) {
790 put_page(page); 808 put_page(page);
791 hugetlb_put_quota(mapping);
792 if (err == -EEXIST) 809 if (err == -EEXIST)
793 goto retry; 810 goto retry;
794 goto out; 811 goto out;
795 } 812 }
813
814 spin_lock(&inode->i_lock);
815 inode->i_blocks += BLOCKS_PER_HUGEPAGE;
816 spin_unlock(&inode->i_lock);
796 } else 817 } else
797 lock_page(page); 818 lock_page(page);
798 } 819 }
@@ -822,7 +843,6 @@ out:
822 843
823backout: 844backout:
824 spin_unlock(&mm->page_table_lock); 845 spin_unlock(&mm->page_table_lock);
825 hugetlb_put_quota(mapping);
826 unlock_page(page); 846 unlock_page(page);
827 put_page(page); 847 put_page(page);
828 goto out; 848 goto out;
@@ -868,7 +888,8 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
868 888
869int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, 889int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
870 struct page **pages, struct vm_area_struct **vmas, 890 struct page **pages, struct vm_area_struct **vmas,
871 unsigned long *position, int *length, int i) 891 unsigned long *position, int *length, int i,
892 int write)
872{ 893{
873 unsigned long pfn_offset; 894 unsigned long pfn_offset;
874 unsigned long vaddr = *position; 895 unsigned long vaddr = *position;
@@ -890,7 +911,7 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
890 int ret; 911 int ret;
891 912
892 spin_unlock(&mm->page_table_lock); 913 spin_unlock(&mm->page_table_lock);
893 ret = hugetlb_fault(mm, vma, vaddr, 0); 914 ret = hugetlb_fault(mm, vma, vaddr, write);
894 spin_lock(&mm->page_table_lock); 915 spin_lock(&mm->page_table_lock);
895 if (!(ret & VM_FAULT_ERROR)) 916 if (!(ret & VM_FAULT_ERROR))
896 continue; 917 continue;
@@ -1132,6 +1153,8 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to)
1132 if (chg < 0) 1153 if (chg < 0)
1133 return chg; 1154 return chg;
1134 1155
1156 if (hugetlb_get_quota(inode->i_mapping, chg))
1157 return -ENOSPC;
1135 ret = hugetlb_acct_memory(chg); 1158 ret = hugetlb_acct_memory(chg);
1136 if (ret < 0) 1159 if (ret < 0)
1137 return ret; 1160 return ret;
@@ -1142,5 +1165,11 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to)
1142void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed) 1165void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed)
1143{ 1166{
1144 long chg = region_truncate(&inode->i_mapping->private_list, offset); 1167 long chg = region_truncate(&inode->i_mapping->private_list, offset);
1145 hugetlb_acct_memory(freed - chg); 1168
1169 spin_lock(&inode->i_lock);
1170 inode->i_blocks -= BLOCKS_PER_HUGEPAGE * freed;
1171 spin_unlock(&inode->i_lock);
1172
1173 hugetlb_put_quota(inode->i_mapping, (chg - freed));
1174 hugetlb_acct_memory(-(chg - freed));
1146} 1175}