aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2011-01-20 17:44:18 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-20 20:02:05 -0500
commit453c719261c0b4030b2676124adb6e81c5fb6833 (patch)
treea90af16797ccb11133046fccdeb52725e2f09167
parent6a108a14fa356ef607be308b68337939e56ea94e (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 <hannes@cmpxchg.org> Reported-by: Ilya Dryomov <idryomov@gmail.com> Reported-by: werner <w.landgraf@ru.ru> Cc: Andrea Arcangeli <aarcange@redhat.com> Tested-by: Ilya Dryomov <idryomov@gmail.com> Tested-by: Steven Rostedt <rostedt@goodmis.org Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/huge_memory.c3
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,
1837 spin_lock(ptl); 1837 spin_lock(ptl);
1838 isolated = __collapse_huge_page_isolate(vma, address, pte); 1838 isolated = __collapse_huge_page_isolate(vma, address, pte);
1839 spin_unlock(ptl); 1839 spin_unlock(ptl);
1840 pte_unmap(pte);
1841 1840
1842 if (unlikely(!isolated)) { 1841 if (unlikely(!isolated)) {
1842 pte_unmap(pte);
1843 spin_lock(&mm->page_table_lock); 1843 spin_lock(&mm->page_table_lock);
1844 BUG_ON(!pmd_none(*pmd)); 1844 BUG_ON(!pmd_none(*pmd));
1845 set_pmd_at(mm, address, pmd, _pmd); 1845 set_pmd_at(mm, address, pmd, _pmd);
@@ -1856,6 +1856,7 @@ static void collapse_huge_page(struct mm_struct *mm,
1856 anon_vma_unlock(vma->anon_vma); 1856 anon_vma_unlock(vma->anon_vma);
1857 1857
1858 __collapse_huge_page_copy(pte, new_page, vma, address, ptl); 1858 __collapse_huge_page_copy(pte, new_page, vma, address, ptl);
1859 pte_unmap(pte);
1859 __SetPageUptodate(new_page); 1860 __SetPageUptodate(new_page);
1860 pgtable = pmd_pgtable(_pmd); 1861 pgtable = pmd_pgtable(_pmd);
1861 VM_BUG_ON(page_count(pgtable) != 1); 1862 VM_BUG_ON(page_count(pgtable) != 1);