aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 347e5fad1cfa..e01abb908b6b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1247,16 +1247,24 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
1247 do { 1247 do {
1248 next = pmd_addr_end(addr, end); 1248 next = pmd_addr_end(addr, end);
1249 if (pmd_trans_huge(*pmd)) { 1249 if (pmd_trans_huge(*pmd)) {
1250 if (next-addr != HPAGE_PMD_SIZE) { 1250 if (next - addr != HPAGE_PMD_SIZE) {
1251 VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem)); 1251 VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem));
1252 split_huge_page_pmd(vma->vm_mm, pmd); 1252 split_huge_page_pmd(vma->vm_mm, pmd);
1253 } else if (zap_huge_pmd(tlb, vma, pmd, addr)) 1253 } else if (zap_huge_pmd(tlb, vma, pmd, addr))
1254 continue; 1254 goto next;
1255 /* fall through */ 1255 /* fall through */
1256 } 1256 }
1257 if (pmd_none_or_clear_bad(pmd)) 1257 /*
1258 continue; 1258 * Here there can be other concurrent MADV_DONTNEED or
1259 * trans huge page faults running, and if the pmd is
1260 * none or trans huge it can change under us. This is
1261 * because MADV_DONTNEED holds the mmap_sem in read
1262 * mode.
1263 */
1264 if (pmd_none_or_trans_huge_or_clear_bad(pmd))
1265 goto next;
1259 next = zap_pte_range(tlb, vma, pmd, addr, next, details); 1266 next = zap_pte_range(tlb, vma, pmd, addr, next, details);
1267next:
1260 cond_resched(); 1268 cond_resched();
1261 } while (pmd++, addr = next, addr != end); 1269 } while (pmd++, addr = next, addr != end);
1262 1270