diff options
author | Rik van Riel <riel@redhat.com> | 2010-08-09 20:19:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-09 23:45:02 -0400 |
commit | ad8c2ee801ad7a52d919b478d9b2c7b39a72d295 (patch) | |
tree | bc56cc023da3467447b0aecd30c0516881d53992 /mm | |
parent | 51b1bd2ace1595b72956224deda349efa880b693 (diff) |
rmap: add exclusive page to private anon_vma on swapin
On swapin it is fairly common for a page to be owned exclusively by one
process. In that case we want to add the page to the anon_vma of that
process's VMA, instead of to the root anon_vma.
This will reduce the amount of rmap searching that the swapout code needs
to do.
Signed-off-by: Rik van Riel <riel@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memory.c | 4 | ||||
-rw-r--r-- | mm/rmap.c | 13 |
2 files changed, 15 insertions, 2 deletions
diff --git a/mm/memory.c b/mm/memory.c index 6b0c37dcfd16..6bc039486e9f 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2628,6 +2628,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2628 | swp_entry_t entry; | 2628 | swp_entry_t entry; |
2629 | pte_t pte; | 2629 | pte_t pte; |
2630 | struct mem_cgroup *ptr = NULL; | 2630 | struct mem_cgroup *ptr = NULL; |
2631 | int exclusive = 0; | ||
2631 | int ret = 0; | 2632 | int ret = 0; |
2632 | 2633 | ||
2633 | if (!pte_unmap_same(mm, pmd, page_table, orig_pte)) | 2634 | if (!pte_unmap_same(mm, pmd, page_table, orig_pte)) |
@@ -2722,10 +2723,11 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2722 | if ((flags & FAULT_FLAG_WRITE) && reuse_swap_page(page)) { | 2723 | if ((flags & FAULT_FLAG_WRITE) && reuse_swap_page(page)) { |
2723 | pte = maybe_mkwrite(pte_mkdirty(pte), vma); | 2724 | pte = maybe_mkwrite(pte_mkdirty(pte), vma); |
2724 | flags &= ~FAULT_FLAG_WRITE; | 2725 | flags &= ~FAULT_FLAG_WRITE; |
2726 | exclusive = 1; | ||
2725 | } | 2727 | } |
2726 | flush_icache_page(vma, page); | 2728 | flush_icache_page(vma, page); |
2727 | set_pte_at(mm, address, page_table, pte); | 2729 | set_pte_at(mm, address, page_table, pte); |
2728 | page_add_anon_rmap(page, vma, address); | 2730 | do_page_add_anon_rmap(page, vma, address, exclusive); |
2729 | /* It's better to call commit-charge after rmap is established */ | 2731 | /* It's better to call commit-charge after rmap is established */ |
2730 | mem_cgroup_commit_charge_swapin(page, ptr); | 2732 | mem_cgroup_commit_charge_swapin(page, ptr); |
2731 | 2733 | ||
@@ -830,6 +830,17 @@ static void __page_check_anon_rmap(struct page *page, | |||
830 | void page_add_anon_rmap(struct page *page, | 830 | void page_add_anon_rmap(struct page *page, |
831 | struct vm_area_struct *vma, unsigned long address) | 831 | struct vm_area_struct *vma, unsigned long address) |
832 | { | 832 | { |
833 | do_page_add_anon_rmap(page, vma, address, 0); | ||
834 | } | ||
835 | |||
836 | /* | ||
837 | * Special version of the above for do_swap_page, which often runs | ||
838 | * into pages that are exclusively owned by the current process. | ||
839 | * Everybody else should continue to use page_add_anon_rmap above. | ||
840 | */ | ||
841 | void do_page_add_anon_rmap(struct page *page, | ||
842 | struct vm_area_struct *vma, unsigned long address, int exclusive) | ||
843 | { | ||
833 | int first = atomic_inc_and_test(&page->_mapcount); | 844 | int first = atomic_inc_and_test(&page->_mapcount); |
834 | if (first) | 845 | if (first) |
835 | __inc_zone_page_state(page, NR_ANON_PAGES); | 846 | __inc_zone_page_state(page, NR_ANON_PAGES); |
@@ -839,7 +850,7 @@ void page_add_anon_rmap(struct page *page, | |||
839 | VM_BUG_ON(!PageLocked(page)); | 850 | VM_BUG_ON(!PageLocked(page)); |
840 | VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 851 | VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end); |
841 | if (first) | 852 | if (first) |
842 | __page_set_anon_rmap(page, vma, address, 0); | 853 | __page_set_anon_rmap(page, vma, address, exclusive); |
843 | else | 854 | else |
844 | __page_check_anon_rmap(page, vma, address); | 855 | __page_check_anon_rmap(page, vma, address); |
845 | } | 856 | } |