diff options
author | Hugh Dickins <hugh@veritas.com> | 2005-04-19 16:29:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org.(none)> | 2005-04-19 16:29:18 -0400 |
commit | 021740dc30d184e3b0fa7679936e65a56090c425 (patch) | |
tree | c31bd23fe74038b4bab5148e17e07745b75b453d /arch | |
parent | 146425a316fb937fbdcac018b34a23c67d12214b (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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/mm/hugetlbpage.c | 11 | ||||
-rw-r--r-- | arch/ppc64/mm/hugetlbpage.c | 37 |
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 | ||