]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[PATCH] Direct Migration V9: remove_from_swap() to remove swap ptes
authorChristoph Lameter <clameter@sgi.com>
Wed, 1 Feb 2006 11:05:39 +0000 (03:05 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 1 Feb 2006 16:53:16 +0000 (08:53 -0800)
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>
include/linux/rmap.h
include/linux/swap.h
mm/rmap.c
mm/swapfile.c
mm/vmscan.c

index 0f1ea2d6ed8635ec2db577254a4265eee1534728..d6b9bcd1384c2767fcef3c2a024ff2c780b65d47 100644 (file)
@@ -92,6 +92,7 @@ static inline void page_dup_rmap(struct page *page)
  */
 int page_referenced(struct page *, int is_locked);
 int try_to_unmap(struct page *, int ignore_refs);
+void remove_from_swap(struct page *page);
 
 /*
  * Called from mm/filemap_xip.c to unmap empty zero page
index d359fc022433fec159261b43e7f1026aa6b3761c..229b6d04b4b62d18bde8494910bcf9ce6d59b369 100644 (file)
@@ -248,6 +248,7 @@ extern int remove_exclusive_swap_page(struct page *);
 struct backing_dev_info;
 
 extern spinlock_t swap_lock;
+extern int remove_vma_swap(struct vm_area_struct *vma, struct page *page);
 
 /* linux/mm/thrash.c */
 extern struct mm_struct * swap_token_mm;
index 13fad5fcdf7996eab9812d5cb781d9157f8cc55e..f4b91d7aa5cfb4f3b7d79ef4258bb08985d92b04 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -206,6 +206,35 @@ out:
        return anon_vma;
 }
 
+#ifdef CONFIG_MIGRATION
+/*
+ * Remove an anonymous page from swap replacing the swap pte's
+ * through real pte's pointing to valid pages and then releasing
+ * the page from the swap cache.
+ *
+ * Must hold page lock on page.
+ */
+void remove_from_swap(struct page *page)
+{
+       struct anon_vma *anon_vma;
+       struct vm_area_struct *vma;
+
+       if (!PageAnon(page) || !PageSwapCache(page))
+               return;
+
+       anon_vma = page_lock_anon_vma(page);
+       if (!anon_vma)
+               return;
+
+       list_for_each_entry(vma, &anon_vma->head, anon_vma_node)
+               remove_vma_swap(vma, page);
+
+       spin_unlock(&anon_vma->lock);
+
+       delete_from_swap_cache(page);
+}
+#endif
+
 /*
  * At what user virtual address is page expected in vma?
  */
index 9678182e0eef64e9fba429d1068cae246ba8bd16..1f9cf0d073b84caad71234ddfb091618906d3047 100644 (file)
@@ -554,6 +554,15 @@ static int unuse_mm(struct mm_struct *mm,
        return 0;
 }
 
+#ifdef CONFIG_MIGRATION
+int remove_vma_swap(struct vm_area_struct *vma, struct page *page)
+{
+       swp_entry_t entry = { .val = page_private(page) };
+
+       return unuse_vma(vma, entry, page);
+}
+#endif
+
 /*
  * Scan swap_map from current position to next entry still in use.
  * Recycle to start on reaching the end, returning 0 when empty.
index 8f326ce2b690bf63953dde56bf365773fad52c21..5e98b86feb74d816c316f383fde56d42f01ba1f0 100644 (file)
@@ -804,6 +804,15 @@ int migrate_page(struct page *newpage, struct page *page)
 
        migrate_page_copy(newpage, page);
 
+       /*
+        * Remove auxiliary swap entries and replace
+        * them with real ptes.
+        *
+        * Note that a real pte entry will allow processes that are not
+        * waiting on the page lock to use the new page via the page tables
+        * before the new page is unlocked.
+        */
+       remove_from_swap(newpage);
        return 0;
 }