diff options
Diffstat (limited to 'mm/rmap.c')
-rw-r--r-- | mm/rmap.c | 57 |
1 files changed, 44 insertions, 13 deletions
@@ -435,6 +435,30 @@ int page_referenced(struct page *page, int is_locked) | |||
435 | } | 435 | } |
436 | 436 | ||
437 | /** | 437 | /** |
438 | * page_set_anon_rmap - setup new anonymous rmap | ||
439 | * @page: the page to add the mapping to | ||
440 | * @vma: the vm area in which the mapping is added | ||
441 | * @address: the user virtual address mapped | ||
442 | */ | ||
443 | static void __page_set_anon_rmap(struct page *page, | ||
444 | struct vm_area_struct *vma, unsigned long address) | ||
445 | { | ||
446 | struct anon_vma *anon_vma = vma->anon_vma; | ||
447 | |||
448 | BUG_ON(!anon_vma); | ||
449 | anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; | ||
450 | page->mapping = (struct address_space *) anon_vma; | ||
451 | |||
452 | page->index = linear_page_index(vma, address); | ||
453 | |||
454 | /* | ||
455 | * nr_mapped state can be updated without turning off | ||
456 | * interrupts because it is not modified via interrupt. | ||
457 | */ | ||
458 | __inc_page_state(nr_mapped); | ||
459 | } | ||
460 | |||
461 | /** | ||
438 | * page_add_anon_rmap - add pte mapping to an anonymous page | 462 | * page_add_anon_rmap - add pte mapping to an anonymous page |
439 | * @page: the page to add the mapping to | 463 | * @page: the page to add the mapping to |
440 | * @vma: the vm area in which the mapping is added | 464 | * @vma: the vm area in which the mapping is added |
@@ -445,20 +469,27 @@ int page_referenced(struct page *page, int is_locked) | |||
445 | void page_add_anon_rmap(struct page *page, | 469 | void page_add_anon_rmap(struct page *page, |
446 | struct vm_area_struct *vma, unsigned long address) | 470 | struct vm_area_struct *vma, unsigned long address) |
447 | { | 471 | { |
448 | if (atomic_inc_and_test(&page->_mapcount)) { | 472 | if (atomic_inc_and_test(&page->_mapcount)) |
449 | struct anon_vma *anon_vma = vma->anon_vma; | 473 | __page_set_anon_rmap(page, vma, address); |
450 | |||
451 | BUG_ON(!anon_vma); | ||
452 | anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; | ||
453 | page->mapping = (struct address_space *) anon_vma; | ||
454 | |||
455 | page->index = linear_page_index(vma, address); | ||
456 | |||
457 | inc_page_state(nr_mapped); | ||
458 | } | ||
459 | /* else checking page index and mapping is racy */ | 474 | /* else checking page index and mapping is racy */ |
460 | } | 475 | } |
461 | 476 | ||
477 | /* | ||
478 | * page_add_new_anon_rmap - add pte mapping to a new anonymous page | ||
479 | * @page: the page to add the mapping to | ||
480 | * @vma: the vm area in which the mapping is added | ||
481 | * @address: the user virtual address mapped | ||
482 | * | ||
483 | * Same as page_add_anon_rmap but must only be called on *new* pages. | ||
484 | * This means the inc-and-test can be bypassed. | ||
485 | */ | ||
486 | void page_add_new_anon_rmap(struct page *page, | ||
487 | struct vm_area_struct *vma, unsigned long address) | ||
488 | { | ||
489 | atomic_set(&page->_mapcount, 0); /* elevate count by 1 (starts at -1) */ | ||
490 | __page_set_anon_rmap(page, vma, address); | ||
491 | } | ||
492 | |||
462 | /** | 493 | /** |
463 | * page_add_file_rmap - add pte mapping to a file page | 494 | * page_add_file_rmap - add pte mapping to a file page |
464 | * @page: the page to add the mapping to | 495 | * @page: the page to add the mapping to |
@@ -471,7 +502,7 @@ void page_add_file_rmap(struct page *page) | |||
471 | BUG_ON(!pfn_valid(page_to_pfn(page))); | 502 | BUG_ON(!pfn_valid(page_to_pfn(page))); |
472 | 503 | ||
473 | if (atomic_inc_and_test(&page->_mapcount)) | 504 | if (atomic_inc_and_test(&page->_mapcount)) |
474 | inc_page_state(nr_mapped); | 505 | __inc_page_state(nr_mapped); |
475 | } | 506 | } |
476 | 507 | ||
477 | /** | 508 | /** |
@@ -495,7 +526,7 @@ void page_remove_rmap(struct page *page) | |||
495 | */ | 526 | */ |
496 | if (page_test_and_clear_dirty(page)) | 527 | if (page_test_and_clear_dirty(page)) |
497 | set_page_dirty(page); | 528 | set_page_dirty(page); |
498 | dec_page_state(nr_mapped); | 529 | __dec_page_state(nr_mapped); |
499 | } | 530 | } |
500 | } | 531 | } |
501 | 532 | ||