diff options
author | Kukjin Kim <kgene.kim@samsung.com> | 2014-07-29 06:09:42 +0900 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2014-07-29 06:09:42 +0900 |
commit | 6da287ad0266cca1fa8f88fb8b1c466e8164671f (patch) | |
tree | cfdf86c200bf9f1199c45acf51644fc185c705ec /mm/rmap.c | |
parent | ccaba4527156da1619a23bafcb944e8e029d0573 (diff) | |
parent | 6887d9e5682886b5d9fe81217ff2f1410724cdb9 (diff) |
Merge branch 'v3.17-next/power-exynos' into v3.17-next/dt-samsung-2
Diffstat (limited to 'mm/rmap.c')
-rw-r--r-- | mm/rmap.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/mm/rmap.c b/mm/rmap.c index bf05fc872ae8..b7e94ebbd09e 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -569,6 +569,7 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address) pgd_t *pgd; pud_t *pud; pmd_t *pmd = NULL; + pmd_t pmde; pgd = pgd_offset(mm, address); if (!pgd_present(*pgd)) @@ -579,7 +580,13 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address) goto out; pmd = pmd_offset(pud, address); - if (!pmd_present(*pmd)) + /* + * Some THP functions use the sequence pmdp_clear_flush(), set_pmd_at() + * without holding anon_vma lock for write. So when looking for a + * genuine pmde (in which to find pte), test present and !THP together. + */ + pmde = ACCESS_ONCE(*pmd); + if (!pmd_present(pmde) || pmd_trans_huge(pmde)) pmd = NULL; out: return pmd; @@ -615,9 +622,6 @@ pte_t *__page_check_address(struct page *page, struct mm_struct *mm, if (!pmd) return NULL; - if (pmd_trans_huge(*pmd)) - return NULL; - pte = pte_offset_map(pmd, address); /* Make a quick check before getting the lock */ if (!sync && !pte_present(*pte)) { |