aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugh Dickins <hugh@veritas.com>2005-04-19 16:29:18 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org.(none)>2005-04-19 16:29:18 -0400
commit021740dc30d184e3b0fa7679936e65a56090c425 (patch)
treec31bd23fe74038b4bab5148e17e07745b75b453d
parent146425a316fb937fbdcac018b34a23c67d12214b (diff)
[PATCH] freepgt: hugetlb area is clean
Once we're strict about clearing away page tables, hugetlb_prefault can assume there are no page tables left within its range. Since the other arches continue if !pte_none here, let i386 do the same. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/mm/hugetlbpage.c11
-rw-r--r--arch/ppc64/mm/hugetlbpage.c37
2 files changed, 2 insertions, 46 deletions
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
index a8c45143088b..171fc925e1e4 100644
--- a/arch/i386/mm/hugetlbpage.c
+++ b/arch/i386/mm/hugetlbpage.c
@@ -249,15 +249,8 @@ int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
249 goto out; 249 goto out;
250 } 250 }
251 251
252 if (!pte_none(*pte)) { 252 if (!pte_none(*pte))
253 pmd_t *pmd = (pmd_t *) pte; 253 continue;
254
255 page = pmd_page(*pmd);
256 pmd_clear(pmd);
257 mm->nr_ptes--;
258 dec_page_state(nr_page_table_pages);
259 page_cache_release(page);
260 }
261 254
262 idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) 255 idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
263 + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); 256 + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c
index 8665bb57e42b..390296efe3e0 100644
--- a/arch/ppc64/mm/hugetlbpage.c
+++ b/arch/ppc64/mm/hugetlbpage.c
@@ -203,8 +203,6 @@ static int prepare_low_seg_for_htlb(struct mm_struct *mm, unsigned long seg)
203 unsigned long start = seg << SID_SHIFT; 203 unsigned long start = seg << SID_SHIFT;
204 unsigned long end = (seg+1) << SID_SHIFT; 204 unsigned long end = (seg+1) << SID_SHIFT;
205 struct vm_area_struct *vma; 205 struct vm_area_struct *vma;
206 unsigned long addr;
207 struct mmu_gather *tlb;
208 206
209 BUG_ON(seg >= 16); 207 BUG_ON(seg >= 16);
210 208
@@ -213,41 +211,6 @@ static int prepare_low_seg_for_htlb(struct mm_struct *mm, unsigned long seg)
213 if (vma && (vma->vm_start < end)) 211 if (vma && (vma->vm_start < end))
214 return -EBUSY; 212 return -EBUSY;
215 213
216 /* Clean up any leftover PTE pages in the region */
217 spin_lock(&mm->page_table_lock);
218 tlb = tlb_gather_mmu(mm, 0);
219 for (addr = start; addr < end; addr += PMD_SIZE) {
220 pgd_t *pgd = pgd_offset(mm, addr);
221 pmd_t *pmd;
222 struct page *page;
223 pte_t *pte;
224 int i;
225
226 if (pgd_none(*pgd))
227 continue;
228 pmd = pmd_offset(pgd, addr);
229 if (!pmd || pmd_none(*pmd))
230 continue;
231 if (pmd_bad(*pmd)) {
232 pmd_ERROR(*pmd);
233 pmd_clear(pmd);
234 continue;
235 }
236 pte = (pte_t *)pmd_page_kernel(*pmd);
237 /* No VMAs, so there should be no PTEs, check just in case. */
238 for (i = 0; i < PTRS_PER_PTE; i++) {
239 BUG_ON(!pte_none(*pte));
240 pte++;
241 }
242 page = pmd_page(*pmd);
243 pmd_clear(pmd);
244 mm->nr_ptes--;
245 dec_page_state(nr_page_table_pages);
246 pte_free_tlb(tlb, page);
247 }
248 tlb_finish_mmu(tlb, start, end);
249 spin_unlock(&mm->page_table_lock);
250
251 return 0; 214 return 0;
252} 215}
253 216