aboutsummaryrefslogtreecommitdiffstats
path: root/mm/rmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/rmap.c')
-rw-r--r--mm/rmap.c58
1 files changed, 20 insertions, 38 deletions
diff --git a/mm/rmap.c b/mm/rmap.c
index 914d04b98bee..491ac350048f 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -225,7 +225,7 @@ vma_address(struct page *page, struct vm_area_struct *vma)
225 225
226/* 226/*
227 * At what user virtual address is page expected in vma? checking that the 227 * At what user virtual address is page expected in vma? checking that the
228 * page matches the vma: currently only used by unuse_process, on anon pages. 228 * page matches the vma: currently only used on anon pages, by unuse_vma;
229 */ 229 */
230unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) 230unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
231{ 231{
@@ -234,7 +234,8 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
234 (void *)page->mapping - PAGE_MAPPING_ANON) 234 (void *)page->mapping - PAGE_MAPPING_ANON)
235 return -EFAULT; 235 return -EFAULT;
236 } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) { 236 } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) {
237 if (vma->vm_file->f_mapping != page->mapping) 237 if (!vma->vm_file ||
238 vma->vm_file->f_mapping != page->mapping)
238 return -EFAULT; 239 return -EFAULT;
239 } else 240 } else
240 return -EFAULT; 241 return -EFAULT;
@@ -289,7 +290,7 @@ pte_t *page_check_address(struct page *page, struct mm_struct *mm,
289 * repeatedly from either page_referenced_anon or page_referenced_file. 290 * repeatedly from either page_referenced_anon or page_referenced_file.
290 */ 291 */
291static int page_referenced_one(struct page *page, 292static int page_referenced_one(struct page *page,
292 struct vm_area_struct *vma, unsigned int *mapcount, int ignore_token) 293 struct vm_area_struct *vma, unsigned int *mapcount)
293{ 294{
294 struct mm_struct *mm = vma->vm_mm; 295 struct mm_struct *mm = vma->vm_mm;
295 unsigned long address; 296 unsigned long address;
@@ -310,7 +311,7 @@ static int page_referenced_one(struct page *page,
310 311
311 /* Pretend the page is referenced if the task has the 312 /* Pretend the page is referenced if the task has the
312 swap token and is in the middle of a page fault. */ 313 swap token and is in the middle of a page fault. */
313 if (mm != current->mm && !ignore_token && has_swap_token(mm) && 314 if (mm != current->mm && has_swap_token(mm) &&
314 rwsem_is_locked(&mm->mmap_sem)) 315 rwsem_is_locked(&mm->mmap_sem))
315 referenced++; 316 referenced++;
316 317
@@ -320,7 +321,7 @@ out:
320 return referenced; 321 return referenced;
321} 322}
322 323
323static int page_referenced_anon(struct page *page, int ignore_token) 324static int page_referenced_anon(struct page *page)
324{ 325{
325 unsigned int mapcount; 326 unsigned int mapcount;
326 struct anon_vma *anon_vma; 327 struct anon_vma *anon_vma;
@@ -333,8 +334,7 @@ static int page_referenced_anon(struct page *page, int ignore_token)
333 334
334 mapcount = page_mapcount(page); 335 mapcount = page_mapcount(page);
335 list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { 336 list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
336 referenced += page_referenced_one(page, vma, &mapcount, 337 referenced += page_referenced_one(page, vma, &mapcount);
337 ignore_token);
338 if (!mapcount) 338 if (!mapcount)
339 break; 339 break;
340 } 340 }
@@ -353,7 +353,7 @@ static int page_referenced_anon(struct page *page, int ignore_token)
353 * 353 *
354 * This function is only called from page_referenced for object-based pages. 354 * This function is only called from page_referenced for object-based pages.
355 */ 355 */
356static int page_referenced_file(struct page *page, int ignore_token) 356static int page_referenced_file(struct page *page)
357{ 357{
358 unsigned int mapcount; 358 unsigned int mapcount;
359 struct address_space *mapping = page->mapping; 359 struct address_space *mapping = page->mapping;
@@ -391,8 +391,7 @@ static int page_referenced_file(struct page *page, int ignore_token)
391 referenced++; 391 referenced++;
392 break; 392 break;
393 } 393 }
394 referenced += page_referenced_one(page, vma, &mapcount, 394 referenced += page_referenced_one(page, vma, &mapcount);
395 ignore_token);
396 if (!mapcount) 395 if (!mapcount)
397 break; 396 break;
398 } 397 }
@@ -409,13 +408,10 @@ static int page_referenced_file(struct page *page, int ignore_token)
409 * Quick test_and_clear_referenced for all mappings to a page, 408 * Quick test_and_clear_referenced for all mappings to a page,
410 * returns the number of ptes which referenced the page. 409 * returns the number of ptes which referenced the page.
411 */ 410 */
412int page_referenced(struct page *page, int is_locked, int ignore_token) 411int page_referenced(struct page *page, int is_locked)
413{ 412{
414 int referenced = 0; 413 int referenced = 0;
415 414
416 if (!swap_token_default_timeout)
417 ignore_token = 1;
418
419 if (page_test_and_clear_young(page)) 415 if (page_test_and_clear_young(page))
420 referenced++; 416 referenced++;
421 417
@@ -424,15 +420,14 @@ int page_referenced(struct page *page, int is_locked, int ignore_token)
424 420
425 if (page_mapped(page) && page->mapping) { 421 if (page_mapped(page) && page->mapping) {
426 if (PageAnon(page)) 422 if (PageAnon(page))
427 referenced += page_referenced_anon(page, ignore_token); 423 referenced += page_referenced_anon(page);
428 else if (is_locked) 424 else if (is_locked)
429 referenced += page_referenced_file(page, ignore_token); 425 referenced += page_referenced_file(page);
430 else if (TestSetPageLocked(page)) 426 else if (TestSetPageLocked(page))
431 referenced++; 427 referenced++;
432 else { 428 else {
433 if (page->mapping) 429 if (page->mapping)
434 referenced += page_referenced_file(page, 430 referenced += page_referenced_file(page);
435 ignore_token);
436 unlock_page(page); 431 unlock_page(page);
437 } 432 }
438 } 433 }
@@ -529,10 +524,8 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma)
529 * If the page is mlock()d, we cannot swap it out. 524 * If the page is mlock()d, we cannot swap it out.
530 * If it's recently referenced (perhaps page_referenced 525 * If it's recently referenced (perhaps page_referenced
531 * skipped over this mm) then we should reactivate it. 526 * skipped over this mm) then we should reactivate it.
532 *
533 * Pages belonging to VM_RESERVED regions should not happen here.
534 */ 527 */
535 if ((vma->vm_flags & (VM_LOCKED|VM_RESERVED)) || 528 if ((vma->vm_flags & VM_LOCKED) ||
536 ptep_clear_flush_young(vma, address, pte)) { 529 ptep_clear_flush_young(vma, address, pte)) {
537 ret = SWAP_FAIL; 530 ret = SWAP_FAIL;
538 goto out_unmap; 531 goto out_unmap;
@@ -613,7 +606,6 @@ static void try_to_unmap_cluster(unsigned long cursor,
613 struct page *page; 606 struct page *page;
614 unsigned long address; 607 unsigned long address;
615 unsigned long end; 608 unsigned long end;
616 unsigned long pfn;
617 609
618 address = (vma->vm_start + cursor) & CLUSTER_MASK; 610 address = (vma->vm_start + cursor) & CLUSTER_MASK;
619 end = address + CLUSTER_SIZE; 611 end = address + CLUSTER_SIZE;
@@ -642,15 +634,8 @@ static void try_to_unmap_cluster(unsigned long cursor,
642 for (; address < end; pte++, address += PAGE_SIZE) { 634 for (; address < end; pte++, address += PAGE_SIZE) {
643 if (!pte_present(*pte)) 635 if (!pte_present(*pte))
644 continue; 636 continue;
645 637 page = vm_normal_page(vma, address, *pte);
646 pfn = pte_pfn(*pte); 638 BUG_ON(!page || PageAnon(page));
647 if (unlikely(!pfn_valid(pfn))) {
648 print_bad_pte(vma, *pte, address);
649 continue;
650 }
651
652 page = pfn_to_page(pfn);
653 BUG_ON(PageAnon(page));
654 639
655 if (ptep_clear_flush_young(vma, address, pte)) 640 if (ptep_clear_flush_young(vma, address, pte))
656 continue; 641 continue;
@@ -727,7 +712,7 @@ static int try_to_unmap_file(struct page *page)
727 712
728 list_for_each_entry(vma, &mapping->i_mmap_nonlinear, 713 list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
729 shared.vm_set.list) { 714 shared.vm_set.list) {
730 if (vma->vm_flags & (VM_LOCKED|VM_RESERVED)) 715 if (vma->vm_flags & VM_LOCKED)
731 continue; 716 continue;
732 cursor = (unsigned long) vma->vm_private_data; 717 cursor = (unsigned long) vma->vm_private_data;
733 if (cursor > max_nl_cursor) 718 if (cursor > max_nl_cursor)
@@ -761,7 +746,7 @@ static int try_to_unmap_file(struct page *page)
761 do { 746 do {
762 list_for_each_entry(vma, &mapping->i_mmap_nonlinear, 747 list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
763 shared.vm_set.list) { 748 shared.vm_set.list) {
764 if (vma->vm_flags & (VM_LOCKED|VM_RESERVED)) 749 if (vma->vm_flags & VM_LOCKED)
765 continue; 750 continue;
766 cursor = (unsigned long) vma->vm_private_data; 751 cursor = (unsigned long) vma->vm_private_data;
767 while ( cursor < max_nl_cursor && 752 while ( cursor < max_nl_cursor &&
@@ -783,11 +768,8 @@ static int try_to_unmap_file(struct page *page)
783 * in locked vmas). Reset cursor on all unreserved nonlinear 768 * in locked vmas). Reset cursor on all unreserved nonlinear
784 * vmas, now forgetting on which ones it had fallen behind. 769 * vmas, now forgetting on which ones it had fallen behind.
785 */ 770 */
786 list_for_each_entry(vma, &mapping->i_mmap_nonlinear, 771 list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list)
787 shared.vm_set.list) { 772 vma->vm_private_data = NULL;
788 if (!(vma->vm_flags & VM_RESERVED))
789 vma->vm_private_data = NULL;
790 }
791out: 773out:
792 spin_unlock(&mapping->i_mmap_lock); 774 spin_unlock(&mapping->i_mmap_lock);
793 return ret; 775 return ret;