aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2006-02-01 06:05:39 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-01 11:53:16 -0500
commita3351e525e4768c29aa5d22ef59b5b38e0361e53 (patch)
tree457ab54f402b471c5158e8b361d059e88ab8cd62 /mm
parenta48d07afdf18212de22b959715b16793c5a6e57a (diff)
[PATCH] Direct Migration V9: remove_from_swap() to remove swap ptes
Add remove_from_swap remove_from_swap() allows the restoration of the pte entries that existed before page migration occurred for anonymous pages by walking the reverse maps. This reduces swap use and establishes regular pte's without the need for page faults. Signed-off-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/rmap.c29
-rw-r--r--mm/swapfile.c9
-rw-r--r--mm/vmscan.c9
3 files changed, 47 insertions, 0 deletions
diff --git a/mm/rmap.c b/mm/rmap.c
index 13fad5fcdf79..f4b91d7aa5cf 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -206,6 +206,35 @@ out:
206 return anon_vma; 206 return anon_vma;
207} 207}
208 208
209#ifdef CONFIG_MIGRATION
210/*
211 * Remove an anonymous page from swap replacing the swap pte's
212 * through real pte's pointing to valid pages and then releasing
213 * the page from the swap cache.
214 *
215 * Must hold page lock on page.
216 */
217void remove_from_swap(struct page *page)
218{
219 struct anon_vma *anon_vma;
220 struct vm_area_struct *vma;
221
222 if (!PageAnon(page) || !PageSwapCache(page))
223 return;
224
225 anon_vma = page_lock_anon_vma(page);
226 if (!anon_vma)
227 return;
228
229 list_for_each_entry(vma, &anon_vma->head, anon_vma_node)
230 remove_vma_swap(vma, page);
231
232 spin_unlock(&anon_vma->lock);
233
234 delete_from_swap_cache(page);
235}
236#endif
237
209/* 238/*
210 * At what user virtual address is page expected in vma? 239 * At what user virtual address is page expected in vma?
211 */ 240 */
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 9678182e0eef..1f9cf0d073b8 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -554,6 +554,15 @@ static int unuse_mm(struct mm_struct *mm,
554 return 0; 554 return 0;
555} 555}
556 556
557#ifdef CONFIG_MIGRATION
558int remove_vma_swap(struct vm_area_struct *vma, struct page *page)
559{
560 swp_entry_t entry = { .val = page_private(page) };
561
562 return unuse_vma(vma, entry, page);
563}
564#endif
565
557/* 566/*
558 * Scan swap_map from current position to next entry still in use. 567 * Scan swap_map from current position to next entry still in use.
559 * Recycle to start on reaching the end, returning 0 when empty. 568 * Recycle to start on reaching the end, returning 0 when empty.
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 8f326ce2b690..5e98b86feb74 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -804,6 +804,15 @@ int migrate_page(struct page *newpage, struct page *page)
804 804
805 migrate_page_copy(newpage, page); 805 migrate_page_copy(newpage, page);
806 806
807 /*
808 * Remove auxiliary swap entries and replace
809 * them with real ptes.
810 *
811 * Note that a real pte entry will allow processes that are not
812 * waiting on the page lock to use the new page via the page tables
813 * before the new page is unlocked.
814 */
815 remove_from_swap(newpage);
807 return 0; 816 return 0;
808} 817}
809 818