aboutsummaryrefslogtreecommitdiffstats
path: root/mm/rmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/rmap.c')
-rw-r--r--mm/rmap.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/mm/rmap.c b/mm/rmap.c
index 16521664010d..0895b5c7cbff 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -14,7 +14,7 @@
14 * Original design by Rik van Riel <riel@conectiva.com.br> 2001 14 * Original design by Rik van Riel <riel@conectiva.com.br> 2001
15 * File methods by Dave McCracken <dmccr@us.ibm.com> 2003, 2004 15 * File methods by Dave McCracken <dmccr@us.ibm.com> 2003, 2004
16 * Anonymous methods by Andrea Arcangeli <andrea@suse.de> 2004 16 * Anonymous methods by Andrea Arcangeli <andrea@suse.de> 2004
17 * Contributions by Hugh Dickins <hugh@veritas.com> 2003, 2004 17 * Contributions by Hugh Dickins 2003, 2004
18 */ 18 */
19 19
20/* 20/*
@@ -333,7 +333,9 @@ static int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma)
333 * repeatedly from either page_referenced_anon or page_referenced_file. 333 * repeatedly from either page_referenced_anon or page_referenced_file.
334 */ 334 */
335static int page_referenced_one(struct page *page, 335static int page_referenced_one(struct page *page,
336 struct vm_area_struct *vma, unsigned int *mapcount) 336 struct vm_area_struct *vma,
337 unsigned int *mapcount,
338 unsigned long *vm_flags)
337{ 339{
338 struct mm_struct *mm = vma->vm_mm; 340 struct mm_struct *mm = vma->vm_mm;
339 unsigned long address; 341 unsigned long address;
@@ -356,6 +358,7 @@ static int page_referenced_one(struct page *page,
356 */ 358 */
357 if (vma->vm_flags & VM_LOCKED) { 359 if (vma->vm_flags & VM_LOCKED) {
358 *mapcount = 1; /* break early from loop */ 360 *mapcount = 1; /* break early from loop */
361 *vm_flags |= VM_LOCKED;
359 goto out_unmap; 362 goto out_unmap;
360 } 363 }
361 364
@@ -381,11 +384,14 @@ out_unmap:
381 (*mapcount)--; 384 (*mapcount)--;
382 pte_unmap_unlock(pte, ptl); 385 pte_unmap_unlock(pte, ptl);
383out: 386out:
387 if (referenced)
388 *vm_flags |= vma->vm_flags;
384 return referenced; 389 return referenced;
385} 390}
386 391
387static int page_referenced_anon(struct page *page, 392static int page_referenced_anon(struct page *page,
388 struct mem_cgroup *mem_cont) 393 struct mem_cgroup *mem_cont,
394 unsigned long *vm_flags)
389{ 395{
390 unsigned int mapcount; 396 unsigned int mapcount;
391 struct anon_vma *anon_vma; 397 struct anon_vma *anon_vma;
@@ -405,7 +411,8 @@ static int page_referenced_anon(struct page *page,
405 */ 411 */
406 if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) 412 if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont))
407 continue; 413 continue;
408 referenced += page_referenced_one(page, vma, &mapcount); 414 referenced += page_referenced_one(page, vma,
415 &mapcount, vm_flags);
409 if (!mapcount) 416 if (!mapcount)
410 break; 417 break;
411 } 418 }
@@ -418,6 +425,7 @@ static int page_referenced_anon(struct page *page,
418 * page_referenced_file - referenced check for object-based rmap 425 * page_referenced_file - referenced check for object-based rmap
419 * @page: the page we're checking references on. 426 * @page: the page we're checking references on.
420 * @mem_cont: target memory controller 427 * @mem_cont: target memory controller
428 * @vm_flags: collect encountered vma->vm_flags who actually referenced the page
421 * 429 *
422 * For an object-based mapped page, find all the places it is mapped and 430 * For an object-based mapped page, find all the places it is mapped and
423 * check/clear the referenced flag. This is done by following the page->mapping 431 * check/clear the referenced flag. This is done by following the page->mapping
@@ -427,7 +435,8 @@ static int page_referenced_anon(struct page *page,
427 * This function is only called from page_referenced for object-based pages. 435 * This function is only called from page_referenced for object-based pages.
428 */ 436 */
429static int page_referenced_file(struct page *page, 437static int page_referenced_file(struct page *page,
430 struct mem_cgroup *mem_cont) 438 struct mem_cgroup *mem_cont,
439 unsigned long *vm_flags)
431{ 440{
432 unsigned int mapcount; 441 unsigned int mapcount;
433 struct address_space *mapping = page->mapping; 442 struct address_space *mapping = page->mapping;
@@ -467,7 +476,8 @@ static int page_referenced_file(struct page *page,
467 */ 476 */
468 if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) 477 if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont))
469 continue; 478 continue;
470 referenced += page_referenced_one(page, vma, &mapcount); 479 referenced += page_referenced_one(page, vma,
480 &mapcount, vm_flags);
471 if (!mapcount) 481 if (!mapcount)
472 break; 482 break;
473 } 483 }
@@ -481,29 +491,35 @@ static int page_referenced_file(struct page *page,
481 * @page: the page to test 491 * @page: the page to test
482 * @is_locked: caller holds lock on the page 492 * @is_locked: caller holds lock on the page
483 * @mem_cont: target memory controller 493 * @mem_cont: target memory controller
494 * @vm_flags: collect encountered vma->vm_flags who actually referenced the page
484 * 495 *
485 * Quick test_and_clear_referenced for all mappings to a page, 496 * Quick test_and_clear_referenced for all mappings to a page,
486 * returns the number of ptes which referenced the page. 497 * returns the number of ptes which referenced the page.
487 */ 498 */
488int page_referenced(struct page *page, int is_locked, 499int page_referenced(struct page *page,
489 struct mem_cgroup *mem_cont) 500 int is_locked,
501 struct mem_cgroup *mem_cont,
502 unsigned long *vm_flags)
490{ 503{
491 int referenced = 0; 504 int referenced = 0;
492 505
493 if (TestClearPageReferenced(page)) 506 if (TestClearPageReferenced(page))
494 referenced++; 507 referenced++;
495 508
509 *vm_flags = 0;
496 if (page_mapped(page) && page->mapping) { 510 if (page_mapped(page) && page->mapping) {
497 if (PageAnon(page)) 511 if (PageAnon(page))
498 referenced += page_referenced_anon(page, mem_cont); 512 referenced += page_referenced_anon(page, mem_cont,
513 vm_flags);
499 else if (is_locked) 514 else if (is_locked)
500 referenced += page_referenced_file(page, mem_cont); 515 referenced += page_referenced_file(page, mem_cont,
516 vm_flags);
501 else if (!trylock_page(page)) 517 else if (!trylock_page(page))
502 referenced++; 518 referenced++;
503 else { 519 else {
504 if (page->mapping) 520 if (page->mapping)
505 referenced += 521 referenced += page_referenced_file(page,
506 page_referenced_file(page, mem_cont); 522 mem_cont, vm_flags);
507 unlock_page(page); 523 unlock_page(page);
508 } 524 }
509 } 525 }
@@ -688,8 +704,10 @@ void page_add_new_anon_rmap(struct page *page,
688 */ 704 */
689void page_add_file_rmap(struct page *page) 705void page_add_file_rmap(struct page *page)
690{ 706{
691 if (atomic_inc_and_test(&page->_mapcount)) 707 if (atomic_inc_and_test(&page->_mapcount)) {
692 __inc_zone_page_state(page, NR_FILE_MAPPED); 708 __inc_zone_page_state(page, NR_FILE_MAPPED);
709 mem_cgroup_update_mapped_file_stat(page, 1);
710 }
693} 711}
694 712
695#ifdef CONFIG_DEBUG_VM 713#ifdef CONFIG_DEBUG_VM
@@ -738,6 +756,7 @@ void page_remove_rmap(struct page *page)
738 mem_cgroup_uncharge_page(page); 756 mem_cgroup_uncharge_page(page);
739 __dec_zone_page_state(page, 757 __dec_zone_page_state(page,
740 PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED); 758 PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED);
759 mem_cgroup_update_mapped_file_stat(page, -1);
741 /* 760 /*
742 * It would be tidy to reset the PageAnon mapping here, 761 * It would be tidy to reset the PageAnon mapping here,
743 * but that might overwrite a racing page_add_anon_rmap 762 * but that might overwrite a racing page_add_anon_rmap
@@ -1202,7 +1221,6 @@ int try_to_unmap(struct page *page, int migration)
1202 return ret; 1221 return ret;
1203} 1222}
1204 1223
1205#ifdef CONFIG_UNEVICTABLE_LRU
1206/** 1224/**
1207 * try_to_munlock - try to munlock a page 1225 * try_to_munlock - try to munlock a page
1208 * @page: the page to be munlocked 1226 * @page: the page to be munlocked
@@ -1226,4 +1244,4 @@ int try_to_munlock(struct page *page)
1226 else 1244 else
1227 return try_to_unmap_file(page, 1, 0); 1245 return try_to_unmap_file(page, 1, 0);
1228} 1246}
1229#endif 1247