summaryrefslogtreecommitdiffstats
path: root/mm/hugetlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r--mm/hugetlb.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 5bf6468a8862..06315560bd23 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -572,6 +572,7 @@ retry_cpuset:
572 if (!vma_has_reserves(vma, chg)) 572 if (!vma_has_reserves(vma, chg))
573 break; 573 break;
574 574
575 SetPagePrivate(page);
575 h->resv_huge_pages--; 576 h->resv_huge_pages--;
576 break; 577 break;
577 } 578 }
@@ -629,15 +630,20 @@ static void free_huge_page(struct page *page)
629 int nid = page_to_nid(page); 630 int nid = page_to_nid(page);
630 struct hugepage_subpool *spool = 631 struct hugepage_subpool *spool =
631 (struct hugepage_subpool *)page_private(page); 632 (struct hugepage_subpool *)page_private(page);
633 bool restore_reserve;
632 634
633 set_page_private(page, 0); 635 set_page_private(page, 0);
634 page->mapping = NULL; 636 page->mapping = NULL;
635 BUG_ON(page_count(page)); 637 BUG_ON(page_count(page));
636 BUG_ON(page_mapcount(page)); 638 BUG_ON(page_mapcount(page));
639 restore_reserve = PagePrivate(page);
637 640
638 spin_lock(&hugetlb_lock); 641 spin_lock(&hugetlb_lock);
639 hugetlb_cgroup_uncharge_page(hstate_index(h), 642 hugetlb_cgroup_uncharge_page(hstate_index(h),
640 pages_per_huge_page(h), page); 643 pages_per_huge_page(h), page);
644 if (restore_reserve)
645 h->resv_huge_pages++;
646
641 if (h->surplus_huge_pages_node[nid] && huge_page_order(h) < MAX_ORDER) { 647 if (h->surplus_huge_pages_node[nid] && huge_page_order(h) < MAX_ORDER) {
642 /* remove the page from active list */ 648 /* remove the page from active list */
643 list_del(&page->lru); 649 list_del(&page->lru);
@@ -2636,6 +2642,8 @@ retry_avoidcopy:
2636 spin_lock(&mm->page_table_lock); 2642 spin_lock(&mm->page_table_lock);
2637 ptep = huge_pte_offset(mm, address & huge_page_mask(h)); 2643 ptep = huge_pte_offset(mm, address & huge_page_mask(h));
2638 if (likely(pte_same(huge_ptep_get(ptep), pte))) { 2644 if (likely(pte_same(huge_ptep_get(ptep), pte))) {
2645 ClearPagePrivate(new_page);
2646
2639 /* Break COW */ 2647 /* Break COW */
2640 huge_ptep_clear_flush(vma, address, ptep); 2648 huge_ptep_clear_flush(vma, address, ptep);
2641 set_huge_pte_at(mm, address, ptep, 2649 set_huge_pte_at(mm, address, ptep,
@@ -2747,6 +2755,7 @@ retry:
2747 goto retry; 2755 goto retry;
2748 goto out; 2756 goto out;
2749 } 2757 }
2758 ClearPagePrivate(page);
2750 2759
2751 spin_lock(&inode->i_lock); 2760 spin_lock(&inode->i_lock);
2752 inode->i_blocks += blocks_per_huge_page(h); 2761 inode->i_blocks += blocks_per_huge_page(h);
@@ -2793,8 +2802,10 @@ retry:
2793 if (!huge_pte_none(huge_ptep_get(ptep))) 2802 if (!huge_pte_none(huge_ptep_get(ptep)))
2794 goto backout; 2803 goto backout;
2795 2804
2796 if (anon_rmap) 2805 if (anon_rmap) {
2806 ClearPagePrivate(page);
2797 hugepage_add_new_anon_rmap(page, vma, address); 2807 hugepage_add_new_anon_rmap(page, vma, address);
2808 }
2798 else 2809 else
2799 page_dup_rmap(page); 2810 page_dup_rmap(page);
2800 new_pte = make_huge_pte(vma, page, ((vma->vm_flags & VM_WRITE) 2811 new_pte = make_huge_pte(vma, page, ((vma->vm_flags & VM_WRITE)