aboutsummaryrefslogtreecommitdiffstats
path: root/mm/pagewalk.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/pagewalk.c')
-rw-r--r--mm/pagewalk.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index 4c9a653ba563..75c1f2878519 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -35,7 +35,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
35 do { 35 do {
36again: 36again:
37 next = pmd_addr_end(addr, end); 37 next = pmd_addr_end(addr, end);
38 if (pmd_none(*pmd)) { 38 if (pmd_none(*pmd) || !walk->vma) {
39 if (walk->pte_hole) 39 if (walk->pte_hole)
40 err = walk->pte_hole(addr, next, walk); 40 err = walk->pte_hole(addr, next, walk);
41 if (err) 41 if (err)
@@ -165,9 +165,6 @@ static int walk_hugetlb_range(unsigned long addr, unsigned long end,
165 * or skip it via the returned value. Return 0 if we do walk over the 165 * or skip it via the returned value. Return 0 if we do walk over the
166 * current vma, and return 1 if we skip the vma. Negative values means 166 * current vma, and return 1 if we skip the vma. Negative values means
167 * error, where we abort the current walk. 167 * error, where we abort the current walk.
168 *
169 * Default check (only VM_PFNMAP check for now) is used when the caller
170 * doesn't define test_walk() callback.
171 */ 168 */
172static int walk_page_test(unsigned long start, unsigned long end, 169static int walk_page_test(unsigned long start, unsigned long end,
173 struct mm_walk *walk) 170 struct mm_walk *walk)
@@ -178,11 +175,19 @@ static int walk_page_test(unsigned long start, unsigned long end,
178 return walk->test_walk(start, end, walk); 175 return walk->test_walk(start, end, walk);
179 176
180 /* 177 /*
181 * Do not walk over vma(VM_PFNMAP), because we have no valid struct 178 * vma(VM_PFNMAP) doesn't have any valid struct pages behind VM_PFNMAP
182 * page backing a VM_PFNMAP range. See also commit a9ff785e4437. 179 * range, so we don't walk over it as we do for normal vmas. However,
180 * Some callers are interested in handling hole range and they don't
181 * want to just ignore any single address range. Such users certainly
182 * define their ->pte_hole() callbacks, so let's delegate them to handle
183 * vma(VM_PFNMAP).
183 */ 184 */
184 if (vma->vm_flags & VM_PFNMAP) 185 if (vma->vm_flags & VM_PFNMAP) {
185 return 1; 186 int err = 1;
187 if (walk->pte_hole)
188 err = walk->pte_hole(start, end, walk);
189 return err ? err : 1;
190 }
186 return 0; 191 return 0;
187} 192}
188 193