diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /mm/pagewalk.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'mm/pagewalk.c')
-rw-r--r-- | mm/pagewalk.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/mm/pagewalk.c b/mm/pagewalk.c index 8b1a2ce21ee5..c3450d533611 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c | |||
@@ -33,18 +33,35 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end, | |||
33 | 33 | ||
34 | pmd = pmd_offset(pud, addr); | 34 | pmd = pmd_offset(pud, addr); |
35 | do { | 35 | do { |
36 | again: | ||
36 | next = pmd_addr_end(addr, end); | 37 | next = pmd_addr_end(addr, end); |
37 | if (pmd_none_or_clear_bad(pmd)) { | 38 | if (pmd_none(*pmd)) { |
38 | if (walk->pte_hole) | 39 | if (walk->pte_hole) |
39 | err = walk->pte_hole(addr, next, walk); | 40 | err = walk->pte_hole(addr, next, walk); |
40 | if (err) | 41 | if (err) |
41 | break; | 42 | break; |
42 | continue; | 43 | continue; |
43 | } | 44 | } |
45 | /* | ||
46 | * This implies that each ->pmd_entry() handler | ||
47 | * needs to know about pmd_trans_huge() pmds | ||
48 | */ | ||
44 | if (walk->pmd_entry) | 49 | if (walk->pmd_entry) |
45 | err = walk->pmd_entry(pmd, addr, next, walk); | 50 | err = walk->pmd_entry(pmd, addr, next, walk); |
46 | if (!err && walk->pte_entry) | 51 | if (err) |
47 | err = walk_pte_range(pmd, addr, next, walk); | 52 | break; |
53 | |||
54 | /* | ||
55 | * Check this here so we only break down trans_huge | ||
56 | * pages when we _need_ to | ||
57 | */ | ||
58 | if (!walk->pte_entry) | ||
59 | continue; | ||
60 | |||
61 | split_huge_page_pmd(walk->mm, pmd); | ||
62 | if (pmd_none_or_clear_bad(pmd)) | ||
63 | goto again; | ||
64 | err = walk_pte_range(pmd, addr, next, walk); | ||
48 | if (err) | 65 | if (err) |
49 | break; | 66 | break; |
50 | } while (pmd++, addr = next, addr != end); | 67 | } while (pmd++, addr = next, addr != end); |
@@ -139,7 +156,6 @@ int walk_page_range(unsigned long addr, unsigned long end, | |||
139 | pgd_t *pgd; | 156 | pgd_t *pgd; |
140 | unsigned long next; | 157 | unsigned long next; |
141 | int err = 0; | 158 | int err = 0; |
142 | struct vm_area_struct *vma; | ||
143 | 159 | ||
144 | if (addr >= end) | 160 | if (addr >= end) |
145 | return err; | 161 | return err; |
@@ -149,15 +165,17 @@ int walk_page_range(unsigned long addr, unsigned long end, | |||
149 | 165 | ||
150 | pgd = pgd_offset(walk->mm, addr); | 166 | pgd = pgd_offset(walk->mm, addr); |
151 | do { | 167 | do { |
168 | struct vm_area_struct *uninitialized_var(vma); | ||
169 | |||
152 | next = pgd_addr_end(addr, end); | 170 | next = pgd_addr_end(addr, end); |
153 | 171 | ||
172 | #ifdef CONFIG_HUGETLB_PAGE | ||
154 | /* | 173 | /* |
155 | * handle hugetlb vma individually because pagetable walk for | 174 | * handle hugetlb vma individually because pagetable walk for |
156 | * the hugetlb page is dependent on the architecture and | 175 | * the hugetlb page is dependent on the architecture and |
157 | * we can't handled it in the same manner as non-huge pages. | 176 | * we can't handled it in the same manner as non-huge pages. |
158 | */ | 177 | */ |
159 | vma = find_vma(walk->mm, addr); | 178 | vma = find_vma(walk->mm, addr); |
160 | #ifdef CONFIG_HUGETLB_PAGE | ||
161 | if (vma && is_vm_hugetlb_page(vma)) { | 179 | if (vma && is_vm_hugetlb_page(vma)) { |
162 | if (vma->vm_end < next) | 180 | if (vma->vm_end < next) |
163 | next = vma->vm_end; | 181 | next = vma->vm_end; |