diff options
author | Tony Lindgren <tony@atomide.com> | 2017-03-06 08:37:53 -0800 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2017-03-06 08:37:53 -0800 |
commit | e24bce8fb4c26bd0d8eca74cbbee1ad049246be3 (patch) | |
tree | c219c2ec183633aa15841fca5b055a09d2d0b980 /mm/pagewalk.c | |
parent | b92675d998a9fa37fe9e0e35053a95b4a23c158b (diff) | |
parent | c1ae3cfa0e89fa1a7ecc4c99031f5e9ae99d9201 (diff) |
Merge tag 'v4.11-rc1' into omap-for-v4.11/fixes
Linux 4.11-rc1
Diffstat (limited to 'mm/pagewalk.c')
-rw-r--r-- | mm/pagewalk.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/mm/pagewalk.c b/mm/pagewalk.c index 207244489a68..03761577ae86 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c @@ -78,14 +78,32 @@ static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end, pud = pud_offset(pgd, addr); do { + again: next = pud_addr_end(addr, end); - if (pud_none_or_clear_bad(pud)) { + if (pud_none(*pud) || !walk->vma) { if (walk->pte_hole) err = walk->pte_hole(addr, next, walk); if (err) break; continue; } + + if (walk->pud_entry) { + spinlock_t *ptl = pud_trans_huge_lock(pud, walk->vma); + + if (ptl) { + err = walk->pud_entry(pud, addr, next, walk); + spin_unlock(ptl); + if (err) + break; + continue; + } + } + + split_huge_pud(walk->vma, pud, addr); + if (pud_none(*pud)) + goto again; + if (walk->pmd_entry || walk->pte_entry) err = walk_pmd_range(pud, addr, next, walk); if (err) |