diff options
author | Johannes Weiner <[email protected]> | 2011-01-20 14:44:18 -0800 |
---|---|---|
committer | Linus Torvalds <[email protected]> | 2011-01-20 17:02:05 -0800 |
commit | 453c719261c0b4030b2676124adb6e81c5fb6833 (patch) | |
tree | a90af16797ccb11133046fccdeb52725e2f09167 | |
parent | 6a108a14fa356ef607be308b68337939e56ea94e (diff) |
thp: keep highpte mapped until it is no longer needed
Two users reported THP-related crashes on 32-bit x86 machines. Their oops
reports indicated an invalid pte, and subsequent code inspection showed
that the highpte is actually used after unmap.
The fix is to unmap the pte only after all operations against it are
finished.
Signed-off-by: Johannes Weiner <[email protected]>
Reported-by: Ilya Dryomov <[email protected]>
Reported-by: werner <[email protected]>
Cc: Andrea Arcangeli <[email protected]>
Tested-by: Ilya Dryomov <[email protected]>
Tested-by: Steven Rostedt <[email protected]
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r-- | mm/huge_memory.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 004c9c2aac78..c4f634b3a48e 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1837,9 +1837,9 @@ static void collapse_huge_page(struct mm_struct *mm, spin_lock(ptl); isolated = __collapse_huge_page_isolate(vma, address, pte); spin_unlock(ptl); - pte_unmap(pte); if (unlikely(!isolated)) { + pte_unmap(pte); spin_lock(&mm->page_table_lock); BUG_ON(!pmd_none(*pmd)); set_pmd_at(mm, address, pmd, _pmd); @@ -1856,6 +1856,7 @@ static void collapse_huge_page(struct mm_struct *mm, anon_vma_unlock(vma->anon_vma); __collapse_huge_page_copy(pte, new_page, vma, address, ptl); + pte_unmap(pte); __SetPageUptodate(new_page); pgtable = pmd_pgtable(_pmd); VM_BUG_ON(page_count(pgtable) != 1); |