Skip to content

Commit

Permalink
hugetlb: fix nr_pmds accounting with shared page tables
Browse files Browse the repository at this point in the history
We account HugeTLB's shared page table to all processes who share it.
The accounting happens during huge_pmd_share().

If somebody populates pud entry under us, we should decrease pagetable's
refcount and decrease nr_pmds of the process.

By mistake, I increase nr_pmds again in this case.  :-/ It will lead to
"BUG: non-zero nr_pmds on freeing mm: 2" on process' exit.

Let's fix this by increasing nr_pmds only when we're sure that the page
table will be used.

Link: http://lkml.kernel.org/r/[email protected]
Fixes: dc6c9a3 ("mm: account pmd page tables to the process")
Signed-off-by: Kirill A. Shutemov <[email protected]>
Reported-by: zhongjiang <[email protected]>
Reviewed-by: Mike Kravetz <[email protected]>
Acked-by: Michal Hocko <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
kiryl authored and torvalds committed Jun 25, 2016
1 parent 06d8fbc commit c17b1f4
Showing 1 changed file with 1 addition and 2 deletions.
3 changes: 1 addition & 2 deletions mm/hugetlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -4228,7 +4228,6 @@ pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
if (saddr) {
spte = huge_pte_offset(svma->vm_mm, saddr);
if (spte) {
mm_inc_nr_pmds(mm);
get_page(virt_to_page(spte));
break;
}
Expand All @@ -4243,9 +4242,9 @@ pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
if (pud_none(*pud)) {
pud_populate(mm, pud,
(pmd_t *)((unsigned long)spte & PAGE_MASK));
mm_inc_nr_pmds(mm);
} else {
put_page(virt_to_page(spte));
mm_inc_nr_pmds(mm);
}
spin_unlock(ptl);
out:
Expand Down

0 comments on commit c17b1f4

Please sign in to comment.