Skip to content

Commit

Permalink
mm/hugetlb.c: undo change to page mapcount in fault handler
Browse files Browse the repository at this point in the history
Page mapcount should be updated only if we are sure that the page ends
up in the page table otherwise we would leak if we couldn't COW due to
reservations or if idx is out of bounds.

Signed-off-by: Hillf Danton <dhillf@gmail.com>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Hillf Danton authored and Linus Torvalds committed Jan 23, 2012
1 parent 6568d4a commit 409eb8c
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions mm/hugetlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2508,6 +2508,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
{
struct hstate *h = hstate_vma(vma);
int ret = VM_FAULT_SIGBUS;
int anon_rmap = 0;
pgoff_t idx;
unsigned long size;
struct page *page;
Expand Down Expand Up @@ -2562,14 +2563,13 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
spin_lock(&inode->i_lock);
inode->i_blocks += blocks_per_huge_page(h);
spin_unlock(&inode->i_lock);
page_dup_rmap(page);
} else {
lock_page(page);
if (unlikely(anon_vma_prepare(vma))) {
ret = VM_FAULT_OOM;
goto backout_unlocked;
}
hugepage_add_new_anon_rmap(page, vma, address);
anon_rmap = 1;
}
} else {
/*
Expand All @@ -2582,7 +2582,6 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
VM_FAULT_SET_HINDEX(h - hstates);
goto backout_unlocked;
}
page_dup_rmap(page);
}

/*
Expand All @@ -2606,6 +2605,10 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
if (!huge_pte_none(huge_ptep_get(ptep)))
goto backout;

if (anon_rmap)
hugepage_add_new_anon_rmap(page, vma, address);
else
page_dup_rmap(page);
new_pte = make_huge_pte(vma, page, ((vma->vm_flags & VM_WRITE)
&& (vma->vm_flags & VM_SHARED)));
set_huge_pte_at(mm, address, ptep, new_pte);
Expand Down

0 comments on commit 409eb8c

Please sign in to comment.