aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorRik van Riel <riel@redhat.com>2010-08-09 20:19:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-09 23:45:02 -0400
commitad8c2ee801ad7a52d919b478d9b2c7b39a72d295 (patch)
treebc56cc023da3467447b0aecd30c0516881d53992 /mm
parent51b1bd2ace1595b72956224deda349efa880b693 (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.c4
-rw-r--r--mm/rmap.c13
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
diff --git a/mm/rmap.c b/mm/rmap.c
index 4d152a6d3a89..a7d0f5482634 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -830,6 +830,17 @@ static void __page_check_anon_rmap(struct page *page,
830void page_add_anon_rmap(struct page *page, 830void 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 */
841void 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}