linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* page migration
@ 2005-01-03 17:48 Ray Bryant
  2005-01-03 18:25 ` Dave Hansen
  0 siblings, 1 reply; 72+ messages in thread
From: Ray Bryant @ 2005-01-03 17:48 UTC (permalink / raw)
  To: Dave Hansen; +Cc: Hirokazu Takahashi, Marcello Tosatti, linux-mm

[-- Attachment #1: Type: text/plain, Size: 2811 bytes --]

Resending to some more familiar addresses....

-------- Original Message --------
Subject: Re: page migration
Date: Sun, 26 Dec 2004 16:37:37 -0600
From: Ray Bryant <raybry@sgi.com>
To: Dave Hansen <dave@sr71.net>
References: <41BDFBDC.8060007@sgi.com> <20041213213628.GC27473@logos.cnet>	 
<41C44DE5.7060000@sgi.com> <20041218161339.GA2825@logos.cnet>	 
<41CB11B6.2060303@sgi.com> <1103831159.6888.4.camel@localhost>

Dave,

The attached tar file contains a version of the mhp3 patch with the following
properties:

(1)  It splits out the memory migration patches into a separate series file.
(2)  The remaining patches are in the hotplug directory with its own
       series files.
(3)  Rollup patches for the two sets of patches are included.

If one applies the memory_migration patches first, the result compiles and
links but I admit I have not tested it.

If one then applies the memory_hotplug patch, the result applies cleanly and
if one then diff's the modified files (the ones that mhp3 changes) between the
two trees, that is in tree 1 we have my version of the memory migration
patches followed by my version of the hotplug patches, and in tree2 we have
mhp3 (plus a little patch to add the memory migration menu entries to the ia64
Kconfig file), the result is that the files are identical except for
mm/Makefile, where the line
for

obj-$(CONFIG_MEMORY_MIGRATE) += mmigrate.o

now appears earlier than it used to.

I've been unable to get (either) memory hotplug patch to compile.  It won't
compile for Altix at all, because Altix requires NUMA.  I tried it on a
Pentium machine, but apparently I didn't grab the correct config.

Anyway, the fact that the diff shows the split out patches are equivalent
to the full mhp3 patch should be good enough.

(The output of the comparison is included as the file reorder.diff).

I'd like to see this order of patches become the new order for the memory
hotplug patch.  That way, I won't have to pull the migration patches out
of the hotplug patch every time a new one comes out (I need the migration
code, but not the hotplug code for a project I am working on.)

Do you suppose this can be done???

-- 
Best Regards,
Ray
-----------------------------------------------
                    Ray Bryant
512-453-9679 (work)         512-507-7807 (cell)
raybry@sgi.com             raybry@austin.rr.com
The box said: "Requires Windows 98 or better",
             so I installed Linux.
-----------------------------------------------


-- 
Best Regards,
Ray
-----------------------------------------------
                   Ray Bryant
512-453-9679 (work)         512-507-7807 (cell)
raybry@sgi.com             raybry@austin.rr.com
The box said: "Requires Windows 98 or better",
            so I installed Linux.
-----------------------------------------------

[-- Attachment #2: mhp3_reordered.tgz --]
[-- Type: application/x-gzip, Size: 162360 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread
* Re: migration cache, updated
@ 2005-02-06  2:02 Marcelo Tosatti
  0 siblings, 0 replies; 72+ messages in thread
From: Marcelo Tosatti @ 2005-02-06  2:02 UTC (permalink / raw)
  To: raybry, taka, linux-mm, iwamoto, haveblue, hugh

On Fri, Feb 04, 2005 at 10:08:57AM -0600, Ray Bryant wrote:
> Hirokazu Takahashi wrote:
> >
> >
> >>If I take out the migration cache patch, this "VM: killing ..." problem
> >>goes away.   So it has something to do specifically with the migration
> >>cache code.
> >
> >
> >I've never seen the message though the migration cache code may have
> >some bugs. May I ask you some questions about it?
> >
> > - Which version of kernel did you use for it?
> 
> 2.6.10.  I pulled enough of the mm fixes (2 patches) so that the base
> migration patch from the hotplug tree would work on top of 2.6.10.  AFAIK
> the same problem occurs on 2.6.11-mm2 which is where I started with the
> migration cache patch.  But I admit I haven't tested it there recently.

Ray,

A possibility is that lookup_migration_cache() returns NULL, but for some
reason (?) pte_same() fails, giving us VM_FAULT_OOM which results in 
do_page_fault() killing the task.

Can you a printk in here to confirm this?

do_swap_page():
if (pte_is_migration(orig_pte)) {
+               page = lookup_migration_cache(entry.val);
+               if (!page) {
+                       spin_lock(&mm->page_table_lock);
+                       page_table = pte_offset_map(pmd, address);
+                       if (likely(pte_same(*page_table, orig_pte)))
+                               ret = VM_FAULT_OOM;
+                       else
+                               ret = VM_FAULT_MINOR;
+                       pte_unmap(page_table);
+                       spin_unlock(&mm->page_table_lock);
+                       goto out;
+               }


If that happens not to be the case, please find out what exactly is going
on (ie where the VM_FAULT_OOM is coming from) so we can try to help you. 

Do you have any other VM modifications in this kernel? What are they, except
the process migration code?

BTW, can you please post your process migration code? 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"aart@kvack.org"> aart@kvack.org </a>

^ permalink raw reply	[flat|nested] 72+ messages in thread
* Re: migration cache, updated
@ 2005-01-03 19:25 Ray Bryant
  0 siblings, 0 replies; 72+ messages in thread
From: Ray Bryant @ 2005-01-03 19:25 UTC (permalink / raw)
  To: Marcello Tosatti, Hirokazu Takahashi; +Cc: linux-mm

[-- Attachment #1: Type: text/plain, Size: 1031 bytes --]

Marcello and Takahashi-san,

In working with your migration cache patch, I found out that
if CONFIG_MIGRATE_MEMORY is not set, then the kernel with your patch
applied (on top of my "split out" version of the memory migration
code from the hotplug patch) doesn't link.  (It still expects
migration_space, etc to be defined as externals, and these aren't
defined if CONFIG_MIGRATE_MEMORY is not set.)

Now I realize your patch is probably not "final" (there are a couple
of FIXME's still in there....), but I found the attached patch
useful as it lets my patched kernel compile with or without
CONFIG_MEMORY_MIGRATE set.

I hope you find this useful and will incorporate it into your
migration cache patch.

-- 
Best Regards,
Ray
-----------------------------------------------
                   Ray Bryant
512-453-9679 (work)         512-507-7807 (cell)
raybry@sgi.com             raybry@austin.rr.com
The box said: "Requires Windows 98 or better",
            so I installed Linux.
-----------------------------------------------

[-- Attachment #2: migration_cache_update_fix_link.patch --]
[-- Type: text/plain, Size: 2120 bytes --]

Fix the migration cache patch so that it will link even if
CONFIG_MEMORY_MIGRATE is not set.

Signed-off-by:Ray Bryant <raybry@sgi.com>

Index: linux-2.6.10-rc2-mm4-page-migration-only/include/linux/mm.h
===================================================================
--- linux-2.6.10-rc2-mm4-page-migration-only.orig/include/linux/mm.h	2004-12-29 09:30:00.000000000 -0800
+++ linux-2.6.10-rc2-mm4-page-migration-only/include/linux/mm.h	2004-12-29 09:33:46.000000000 -0800
@@ -279,6 +279,7 @@ struct page {
 #include <linux/swap.h>
 #include <linux/swapops.h> 
 
+#ifdef CONFIG_MEMORY_MIGRATE
 static inline int PageMigration(struct page *page)
 {
         swp_entry_t entry;
@@ -293,7 +294,9 @@ static inline int PageMigration(struct p
 
         return 1;
 }
-
+#else
+#define PageMigration(p)  0
+#endif /* CONFIG_MEMORY_MIGRATE */
 
 /*
  * Methods to modify the page usage count.
@@ -506,9 +509,13 @@ static inline struct address_space *page
 {
 	struct address_space *mapping = page->mapping;
 
+#ifdef CONFIG_MEMORY_MIGRATE
 	if (unlikely(PageMigration(page)))
 		mapping = &migration_space;
 	else if (unlikely(PageSwapCache(page)))
+#else
+ 	if (unlikely(PageSwapCache(page)))
+#endif
 		mapping = &swapper_space;
 	else if (unlikely((unsigned long)mapping & PAGE_MAPPING_ANON))
 		mapping = NULL;
Index: linux-2.6.10-rc2-mm4-page-migration-only/include/linux/swapops.h
===================================================================
--- linux-2.6.10-rc2-mm4-page-migration-only.orig/include/linux/swapops.h	2004-12-29 09:30:00.000000000 -0800
+++ linux-2.6.10-rc2-mm4-page-migration-only/include/linux/swapops.h	2004-12-29 09:36:30.000000000 -0800
@@ -70,6 +70,7 @@ static inline pte_t swp_entry_to_pte(swp
 	return __swp_entry_to_pte(arch_entry);
 }
 
+#ifdef CONFIG_MEMORY_MIGRATE
 static inline int pte_is_migration(pte_t pte)
 {
 	unsigned long swp_type;
@@ -81,6 +82,9 @@ static inline int pte_is_migration(pte_t
 
 	return swp_type == MIGRATION_TYPE;
 }
+#else
+#define pte_is_migration(x) 0
+#endif /* CONFIG_MEMORY_MIGRATE */
 
 static inline pte_t migration_entry_to_pte(swp_entry_t entry)
 {

^ permalink raw reply	[flat|nested] 72+ messages in thread
* migration cache, updated
@ 2004-10-25 21:39 Marcelo Tosatti
  2004-10-26  1:17 ` Hiroyuki KAMEZAWA
                   ` (2 more replies)
  0 siblings, 3 replies; 72+ messages in thread
From: Marcelo Tosatti @ 2004-10-25 21:39 UTC (permalink / raw)
  To: linux-mm; +Cc: Hirokazu Takahashi, IWAMOTO Toshihiro, Dave Hansen, Hugh Dickins

Hi,

This is an improved version of the migration cache patch - 
thanks to everyone who contributed - Hirokazu, Iwamoto, Dave,
Hugh.

Identification of migration pages is now done with SwapCache bit 
and special swap type as suggested.

Also fixed a plethora of other bugs present in the last patch.

It now works fine - survives stress testing.

Hugh - I'm not sure about reusing swap allocation code for this 
anymore - it is designed to deal with storage (all the batching
, extent handling, etc). 

the idr code is smaller - it does only what we need here.

Have to update it to last -mhp version.


diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/include/linux/mm.h linux-2.6.9-rc2-mm4.build/include/linux/mm.h
--- linux-2.6.9-rc2-mm4.mhp.orig/include/linux/mm.h	2004-10-05 15:09:38.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/include/linux/mm.h	2004-10-25 18:42:37.000000000 -0200
@@ -251,6 +251,24 @@ extern int capture_page_range(unsigned l
  * files which need it (119 of them)
  */
 #include <linux/page-flags.h>
+#include <linux/swap.h>
+#include <linux/swapops.h> 
+
+static inline int PageMigration(struct page *page)
+{
+        swp_entry_t entry;
+
+        if (!PageSwapCache(page))
+                return 0;
+
+        entry.val = page->private;
+
+        if (swp_type(entry) != MIGRATION_TYPE)
+                return 0;
+
+        return 1;
+}
+
 
 /*
  * Methods to modify the page usage count.
@@ -458,11 +476,14 @@ void page_address_init(void);
 #define PAGE_MAPPING_ANON	1
 
 extern struct address_space swapper_space;
+extern struct address_space migration_space;
 static inline struct address_space *page_mapping(struct page *page)
 {
 	struct address_space *mapping = page->mapping;
 
-	if (unlikely(PageSwapCache(page)))
+	if (unlikely(PageMigration(page)))
+		mapping = &migration_space;
+	else if (unlikely(PageSwapCache(page)))
 		mapping = &swapper_space;
 	else if (unlikely((unsigned long)mapping & PAGE_MAPPING_ANON))
 		mapping = NULL;
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/include/linux/swap.h linux-2.6.9-rc2-mm4.build/include/linux/swap.h
--- linux-2.6.9-rc2-mm4.mhp.orig/include/linux/swap.h	2004-10-05 15:09:39.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/include/linux/swap.h	2004-10-25 20:42:27.912127704 -0200
@@ -253,6 +253,7 @@ extern sector_t map_swap_page(struct swa
 extern struct swap_info_struct *get_swap_info_struct(unsigned);
 extern int can_share_swap_page(struct page *);
 extern int remove_exclusive_swap_page(struct page *);
+extern int migration_remove_entry(swp_entry_t);
 struct backing_dev_info;
 
 extern struct swap_list_t swap_list;
@@ -321,6 +322,21 @@ static inline swp_entry_t get_swap_page(
 #define grab_swap_token()  do { } while(0)
 #define has_swap_token(x) 0
 
+static inline int PageMigration(struct page *page)
+{
+        swp_entry_t entry;
+
+        if (!PageSwapCache(page))
+                return 0;
+
+        entry.val = page->private;
+
+        if (swp_type(entry) != MIGRATION_TYPE)
+                return 0;
+
+        return 1;
+}
+
 #endif /* CONFIG_SWAP */
 #endif /* __KERNEL__*/
 #endif /* _LINUX_SWAP_H */
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/include/linux/swapops.h linux-2.6.9-rc2-mm4.build/include/linux/swapops.h
--- linux-2.6.9-rc2-mm4.mhp.orig/include/linux/swapops.h	2004-10-05 15:09:35.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/include/linux/swapops.h	2004-10-24 12:15:07.000000000 -0200
@@ -10,7 +10,9 @@
  * swp_entry_t's are *never* stored anywhere in their arch-dependent format.
  */
 #define SWP_TYPE_SHIFT(e)	(sizeof(e.val) * 8 - MAX_SWAPFILES_SHIFT)
-#define SWP_OFFSET_MASK(e)	((1UL << SWP_TYPE_SHIFT(e)) - 1)
+#define SWP_OFFSET_MASK(e)	((1UL << (SWP_TYPE_SHIFT(e))) - 1)
+
+#define MIGRATION_TYPE  (MAX_SWAPFILES - 1)
 
 /*
  * Store a type+offset into a swp_entry_t in an arch-independent format
@@ -30,8 +32,7 @@ static inline swp_entry_t swp_entry(unsi
  */
 static inline unsigned swp_type(swp_entry_t entry)
 {
-	return (entry.val >> SWP_TYPE_SHIFT(entry)) &
-			((1 << MAX_SWAPFILES_SHIFT) - 1);
+	return ((entry.val >> SWP_TYPE_SHIFT(entry)));
 }
 
 /*
@@ -68,3 +69,24 @@ static inline pte_t swp_entry_to_pte(swp
 	BUG_ON(pte_file(__swp_entry_to_pte(arch_entry)));
 	return __swp_entry_to_pte(arch_entry);
 }
+
+static inline int pte_is_migration(pte_t pte)
+{
+	unsigned long swp_type;
+	swp_entry_t arch_entry;
+
+	arch_entry = __pte_to_swp_entry(pte);
+
+	swp_type = __swp_type(arch_entry);
+
+	return swp_type == MIGRATION_TYPE;
+}
+
+static inline pte_t migration_entry_to_pte(swp_entry_t entry)
+{
+	swp_entry_t arch_entry;
+	
+	arch_entry = __swp_entry(MIGRATION_TYPE, swp_offset(entry));
+	return __swp_entry_to_pte(arch_entry);
+}
+
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/mm/fremap.c linux-2.6.9-rc2-mm4.build/mm/fremap.c
--- linux-2.6.9-rc2-mm4.mhp.orig/mm/fremap.c	2004-10-05 15:08:23.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/mm/fremap.c	2004-10-25 20:44:05.185339928 -0200
@@ -11,7 +11,6 @@
 #include <linux/file.h>
 #include <linux/mman.h>
 #include <linux/pagemap.h>
-#include <linux/swapops.h>
 #include <linux/rmap.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
@@ -43,8 +42,14 @@ static inline void zap_pte(struct mm_str
 			}
 		}
 	} else {
-		if (!pte_file(pte))
-			free_swap_and_cache(pte_to_swp_entry(pte));
+		if (!pte_file(pte)) {
+			swp_entry_t swp_entry = pte_to_swp_entry(pte);
+			if (pte_is_migration(pte)) { 
+				migration_remove_entry(swp_entry);
+			} else {
+				free_swap_and_cache(swp_entry);
+			}
+		}
 		pte_clear(ptep);
 	}
 }
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/mm/memory.c linux-2.6.9-rc2-mm4.build/mm/memory.c
--- linux-2.6.9-rc2-mm4.mhp.orig/mm/memory.c	2004-10-05 15:08:23.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/mm/memory.c	2004-10-25 19:35:18.000000000 -0200
@@ -53,7 +53,6 @@
 #include <asm/tlbflush.h>
 #include <asm/pgtable.h>
 
-#include <linux/swapops.h>
 #include <linux/elf.h>
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -456,8 +455,13 @@ static void zap_pte_range(struct mmu_gat
 		 */
 		if (unlikely(details))
 			continue;
-		if (!pte_file(pte))
-			free_swap_and_cache(pte_to_swp_entry(pte));
+		if (!pte_file(pte)) {
+			swp_entry_t swp_entry = pte_to_swp_entry(pte);
+			if (pte_is_migration(pte)) {
+				migration_remove_entry(swp_entry);
+			} else
+				free_swap_and_cache(swp_entry);
+		}
 		pte_clear(ptep);
 	}
 	pte_unmap(ptep-1);
@@ -1408,6 +1412,9 @@ static int do_swap_page(struct mm_struct
 	pte_unmap(page_table);
 	spin_unlock(&mm->page_table_lock);
 again:
+	if (pte_is_migration(orig_pte)) {
+		page = lookup_migration_cache(entry.val);
+	} else {
 	page = lookup_swap_cache(entry);
 	if (!page) {
  		swapin_readahead(entry, address, vma);
@@ -1433,15 +1440,22 @@ again:
 		inc_page_state(pgmajfault);
 		grab_swap_token();
 	}
-
 	mark_page_accessed(page);
 	lock_page(page);
 	if (!PageSwapCache(page)) {
+		/* hiro: add !PageMigration(page) here */
 		/* page-migration has occured */
 		unlock_page(page);
 		page_cache_release(page);
 		goto again;
 	}
+	}
+
+
+	if (pte_is_migration(orig_pte)) {
+		mark_page_accessed(page);
+		lock_page(page);
+	}
 
 	/*
 	 * Back out if somebody else faulted in this pte while we
@@ -1459,10 +1473,14 @@ again:
 	}
 
 	/* The page isn't present yet, go ahead with the fault. */
-		
-	swap_free(entry);
-	if (vm_swap_full())
-		remove_exclusive_swap_page(page);
+
+	if (!pte_is_migration(orig_pte)) {
+		swap_free(entry);
+		if (vm_swap_full())
+			remove_exclusive_swap_page(page);
+	} else {
+		migration_remove_reference(page);
+	}
 
 	mm->rss++;
 	pte = mk_pte(page, vma->vm_page_prot);
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/mm/mmigrate.c linux-2.6.9-rc2-mm4.build/mm/mmigrate.c
--- linux-2.6.9-rc2-mm4.mhp.orig/mm/mmigrate.c	2004-10-05 15:08:23.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/mm/mmigrate.c	2004-10-25 20:34:35.324971872 -0200
@@ -21,6 +21,8 @@
 #include <linux/rmap.h>
 #include <linux/mmigrate.h>
 #include <linux/delay.h>
+#include <linux/idr.h>
+#include <linux/page-flags.h>
 
 /*
  * The concept of memory migration is to replace a target page with
@@ -35,6 +37,159 @@
  * hugetlbpages can be handled in the same way.
  */
 
+struct counter {
+	int i;
+};
+
+struct idr migration_idr;
+
+static struct address_space_operations migration_aops = {
+        .writepage      = NULL,
+        .sync_page      = NULL,
+        .set_page_dirty = __set_page_dirty_nobuffers,
+};
+
+static struct backing_dev_info migration_backing_dev_info = {
+        .memory_backed  = 1,    /* Does not contribute to dirty memory */
+        .unplug_io_fn   = NULL,
+};
+
+struct address_space migration_space = {
+        .page_tree      = RADIX_TREE_INIT(GFP_ATOMIC),
+        .tree_lock      = RW_LOCK_UNLOCKED,
+        .a_ops          = &migration_aops,
+        .flags          = GFP_HIGHUSER,
+        .i_mmap_nonlinear = LIST_HEAD_INIT(migration_space.i_mmap_nonlinear),
+        .backing_dev_info = &migration_backing_dev_info,
+};
+
+int init_migration_cache(void) 
+{
+	idr_init(&migration_idr);
+
+	return 0;
+}
+
+__initcall(init_migration_cache);
+
+struct page *lookup_migration_cache(int id) 
+{ 
+	return find_get_page(&migration_space, id);
+}
+
+void migration_duplicate(swp_entry_t entry)
+{
+	int offset;
+	struct counter *cnt;
+
+	read_lock_irq(&migration_space.tree_lock);
+
+	cnt = idr_find(&migration_idr, swp_offset(entry));
+	cnt->i = cnt->i + 1;
+
+	read_unlock_irq(&migration_space.tree_lock);
+}
+
+void remove_from_migration_cache(struct page *page, int id)
+{
+	write_lock_irq(&migration_space.tree_lock);
+        idr_remove(&migration_idr, id);
+	radix_tree_delete(&migration_space.page_tree, id);
+	ClearPageSwapCache(page);
+	page->private = NULL;
+	write_unlock_irq(&migration_space.tree_lock);
+}
+
+// FIXME: if the page is locked will it be correctly removed from migr cache?
+// check races
+
+int migration_remove_entry(swp_entry_t entry)
+{
+	struct page *page;
+	
+	page = find_get_page(&migration_space, entry.val);
+
+	if (!page)
+		BUG();
+
+	migration_remove_reference(page);
+
+	page_cache_release(page);
+}
+
+int migration_remove_reference(struct page *page)
+{
+	struct counter *c;
+	swp_entry_t entry;
+
+	entry.val = page->private;
+
+	read_lock_irq(&migration_space.tree_lock);
+
+	c = idr_find(&migration_idr, swp_offset(entry));
+
+	read_unlock_irq(&migration_space.tree_lock);
+
+	if (!c->i)
+		BUG();
+
+	c->i--;
+
+	if (!c->i) {
+		lock_page(page);
+		remove_from_migration_cache(page, page->private);
+		unlock_page(page);
+		kfree(c);
+	}
+		
+}
+
+int add_to_migration_cache(struct page *page, int gfp_mask) 
+{
+	int error, offset;
+	struct counter *counter;
+	swp_entry_t entry;
+
+	BUG_ON(PageSwapCache(page));
+
+	BUG_ON(PagePrivate(page));
+
+        if (idr_pre_get(&migration_idr, GFP_ATOMIC) == 0)
+                return -ENOMEM;
+
+	counter = kmalloc(sizeof(struct counter), GFP_KERNEL);
+
+	if (!counter)
+		return -ENOMEM;
+
+	error = radix_tree_preload(gfp_mask);
+
+	counter->i = 0;
+
+	if (!error) {
+		write_lock_irq(&migration_space.tree_lock);
+	        error = idr_get_new_above(&migration_idr, counter, 1, &offset);
+
+		if (error < 0)
+			BUG();
+
+		entry = swp_entry(MIGRATION_TYPE, offset);
+
+		error = radix_tree_insert(&migration_space.page_tree, entry.val,
+							page);
+		if (!error) {
+			page_cache_get(page);
+			SetPageLocked(page);
+			page->private = entry.val;
+			SetPageSwapCache(page);
+		}
+		write_unlock_irq(&migration_space.tree_lock);
+                radix_tree_preload_end();
+
+	}
+
+	return error;
+}
 
 /*
  * Try to writeback a dirty page to free its buffers.
@@ -119,9 +274,11 @@ page_migratable(struct page *page, struc
 	if (PageWriteback(page))
 		return -EAGAIN;
 	/* The page might have been truncated */
-	truncated = !PageSwapCache(newpage) && page_mapping(page) == NULL;
-	if (page_count(page) + truncated <= freeable_page_count)
+	truncated = !PageSwapCache(newpage) &&
+		page_mapping(page) == NULL;
+	if (page_count(page) + truncated <= freeable_page_count) 
 		return truncated ? -ENOENT : 0;
+
 	return -EAGAIN;
 }
 
@@ -400,10 +558,14 @@ migrate_onepage(struct page *page)
 	 */
 #ifdef CONFIG_SWAP
 	if (PageAnon(page) && !PageSwapCache(page))
-		if (!add_to_swap(page, GFP_KERNEL)) {
+		if (add_to_migration_cache(page, GFP_KERNEL)) {
 			unlock_page(page);
 			return ERR_PTR(-ENOSPC);
 		}
+/*		if (!add_to_swap(page, GFP_KERNEL)) {
+			unlock_page(page);
+			return ERR_PTR(-ENOSPC);
+		} */
 #endif /* CONFIG_SWAP */
 	if ((mapping = page_mapping(page)) == NULL) {
 		/* truncation is in progress */
@@ -420,8 +582,9 @@ migrate_onepage(struct page *page)
 		return ERR_PTR(-ENOMEM);
 	}
 
-	if (mapping->a_ops->migrate_page)
+	if (mapping->a_ops && mapping->a_ops->migrate_page) {
 		ret = mapping->a_ops->migrate_page(page, newpage);
+	}
 	else
 		ret = generic_migrate_page(page, newpage, migrate_page_common);
 	if (ret) {
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/mm/page_io.c linux-2.6.9-rc2-mm4.build/mm/page_io.c
--- linux-2.6.9-rc2-mm4.mhp.orig/mm/page_io.c	2004-10-05 15:08:23.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/mm/page_io.c	2004-10-24 12:23:55.000000000 -0200
@@ -15,7 +15,6 @@
 #include <linux/pagemap.h>
 #include <linux/swap.h>
 #include <linux/bio.h>
-#include <linux/swapops.h>
 #include <linux/writeback.h>
 #include <asm/pgtable.h>
 
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/mm/rmap.c linux-2.6.9-rc2-mm4.build/mm/rmap.c
--- linux-2.6.9-rc2-mm4.mhp.orig/mm/rmap.c	2004-10-05 15:08:23.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/mm/rmap.c	2004-10-25 17:31:43.000000000 -0200
@@ -49,7 +49,7 @@
 #include <linux/sched.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
-#include <linux/swapops.h>
+//#include <linux/swapops.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/rmap.h>
@@ -641,22 +646,36 @@ static int try_to_unmap_one(struct page 
 	if (pte_dirty(pteval))
 		set_page_dirty(page);
 
-	if (PageAnon(page)) {
-		swp_entry_t entry = { .val = page->private };
-		/*
-		 * Store the swap location in the pte.
-		 * See handle_pte_fault() ...
-		 */
-		BUG_ON(!PageSwapCache(page));
-		swap_duplicate(entry);
-		if (list_empty(&mm->mmlist)) {
-			spin_lock(&mmlist_lock);
-			list_add(&mm->mmlist, &init_mm.mmlist);
-			spin_unlock(&mmlist_lock);
+		if (PageAnon(page)) {
+			swp_entry_t entry = { .val = page->private };
+			/*
+			 * Store the swap location in the pte.
+			 * See handle_pte_fault() ...
+			 */
+	//		BUG_ON(!PageSwapCache(page));
+			if (PageSwapCache(page) && !PageMigration(page)) {
+				swap_duplicate(entry);
+				if (list_empty(&mm->mmlist)) {
+					spin_lock(&mmlist_lock);
+					list_add(&mm->mmlist, &init_mm.mmlist);
+					spin_unlock(&mmlist_lock);
+				}
+				set_pte(pte, swp_entry_to_pte(entry));
+				BUG_ON(pte_file(*pte));
+			} else if (PageMigration(page)) {
+				// page cache get to reference pte,
+				// remove from migration cache
+				// on zero-users at fault path
+				migration_duplicate(entry);
+				if (list_empty(&mm->mmlist)) {
+					spin_lock(&mmlist_lock);
+					list_add(&mm->mmlist, &init_mm.mmlist);
+					spin_unlock(&mmlist_lock);
+				}
+				set_pte(pte, migration_entry_to_pte(entry));
+				BUG_ON(pte_file(*pte));
+			}
 		}
-		set_pte(pte, swp_entry_to_pte(entry));
-		BUG_ON(pte_file(*pte));
-	}
 
 	mm->rss--;
 	page_remove_rmap(page);
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/mm/shmem.c linux-2.6.9-rc2-mm4.build/mm/shmem.c
--- linux-2.6.9-rc2-mm4.mhp.orig/mm/shmem.c	2004-10-05 15:08:23.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/mm/shmem.c	2004-10-24 12:24:20.000000000 -0200
@@ -42,7 +42,6 @@
 #include <linux/vfs.h>
 #include <linux/blkdev.h>
 #include <linux/security.h>
-#include <linux/swapops.h>
 #include <linux/mempolicy.h>
 #include <linux/namei.h>
 #include <linux/xattr.h>
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/mm/swapfile.c linux-2.6.9-rc2-mm4.build/mm/swapfile.c
diff -Nur --show-c-function linux-2.6.9-rc2-mm4.mhp.orig/mm/vmscan.c linux-2.6.9-rc2-mm4.build/mm/vmscan.c
--- linux-2.6.9-rc2-mm4.mhp.orig/mm/vmscan.c	2004-10-05 15:08:23.000000000 -0300
+++ linux-2.6.9-rc2-mm4.build/mm/vmscan.c	2004-10-25 19:15:56.000000000 -0200
@@ -38,8 +38,6 @@
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
 
-#include <linux/swapops.h>
-
 /*
  * The list of shrinker callbacks used by to apply pressure to
  * ageable caches.
@@ -459,7 +457,9 @@ int shrink_list(struct list_head *page_l
 		}
 
 #ifdef CONFIG_SWAP
-		if (PageSwapCache(page)) {
+		// FIXME: allow relocation of migrate cache pages 
+		// into real swap pages for swapout.
+		if (PageSwapCache(page) && !PageMigration(page)) {
 			swp_entry_t swap = { .val = page->private };
 			__delete_from_swap_cache(page);
 			write_unlock_irq(&mapping->tree_lock);

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"aart@kvack.org"> aart@kvack.org </a>

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2005-02-09 20:48 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-03 17:48 page migration Ray Bryant
2005-01-03 18:25 ` Dave Hansen
2005-01-03 19:04   ` Ray Bryant
2005-01-03 16:24     ` page migration\ Marcelo Tosatti
2005-01-03 17:13       ` Marcelo Tosatti
2005-01-03 20:33         ` Ray Bryant
2005-01-03 18:38           ` Marcelo Tosatti
2005-01-04 15:42             ` Hirokazu Takahashi
2005-01-04 17:34               ` Ray Bryant
2005-01-04 16:11                 ` Marcelo Tosatti
2005-01-05  0:08                 ` page migration Ray Bryant
2005-01-03 20:30       ` Ray Bryant
2005-01-03 19:37     ` Dave Hansen
2005-01-03 20:15       ` Ray Bryant
2005-01-03 20:17         ` William Lee Irwin III
2005-01-03 20:36           ` Ray Bryant
2005-01-04 14:42         ` Hirokazu Takahashi
2005-01-04 17:30           ` Ray Bryant
2005-01-04 17:40             ` process " Dave Hansen
2005-01-04 18:26               ` Ray Bryant
2005-01-07 16:40                 ` page migration patch Ray Bryant
2005-01-10  2:58                   ` Dave Hansen
2005-01-07 16:57                 ` migration cache, updated Ray Bryant
2005-01-10 10:07                   ` Marcelo Tosatti
2005-01-04 22:03   ` page migration Yasunori Goto
2005-01-04 23:58     ` Ray Bryant
  -- strict thread matches above, loose matches on Subject: below --
2005-02-06  2:02 migration cache, updated Marcelo Tosatti
2005-01-03 19:25 Ray Bryant
2004-10-25 21:39 Marcelo Tosatti
2004-10-26  1:17 ` Hiroyuki KAMEZAWA
2004-10-26 12:01   ` Marcelo Tosatti
2004-10-26 23:47     ` Hiroyuki KAMEZAWA
2004-10-26  6:37 ` Hirokazu Takahashi
2004-10-26  9:20   ` Marcelo Tosatti
2004-10-26 13:45     ` Hirokazu Takahashi
2004-10-26 11:41       ` Marcelo Tosatti
2004-10-27 13:40       ` Hirokazu Takahashi
2004-10-26  9:15 ` Hirokazu Takahashi
2004-10-26  9:25   ` Marcelo Tosatti
2004-10-26 14:01     ` Hirokazu Takahashi
2004-10-26 12:24       ` Marcelo Tosatti
2004-10-27  7:25         ` IWAMOTO Toshihiro
2004-10-27 16:27           ` Marcelo Tosatti
2004-10-27 13:48         ` Hirokazu Takahashi
2004-10-28 15:19           ` Marcelo Tosatti
2004-10-28 16:05             ` Marcelo Tosatti
2004-10-28 18:51               ` Dave Hansen
2004-10-28 16:26                 ` Marcelo Tosatti
2004-10-28 20:24                   ` Dave Hansen
2004-11-03 15:21                   ` Marcelo Tosatti
2004-11-04  8:01                     ` Hirokazu Takahashi
2004-11-05 13:49               ` Hirokazu Takahashi
2004-11-05 15:16                 ` Marcelo Tosatti
2004-11-16  4:07                   ` Hirokazu Takahashi
2004-11-23 12:14                     ` Marcelo Tosatti
2004-11-24 10:21                       ` Hirokazu Takahashi
2004-12-01 20:21                         ` Marcelo Tosatti
2004-12-08 13:23                           ` Hirokazu Takahashi
2005-01-17  9:59                             ` Marcelo Tosatti
2005-01-31 18:33                               ` Ray Bryant
2005-01-31 18:44                                 ` Marcelo Tosatti
2005-02-02 21:28                                   ` Ray Bryant
2005-02-03  2:59                                     ` Hirokazu Takahashi
2005-02-03 15:19                                       ` Ray Bryant
2005-02-04  7:32                                         ` Hirokazu Takahashi
2005-02-04 16:08                                           ` Ray Bryant
2005-02-07 12:46                                             ` Hirokazu Takahashi
2005-02-07 20:54                                               ` Ray Bryant
2005-02-08  2:17                                                 ` Hirokazu Takahashi
     [not found]                                                   ` <42083913.9050306@sgi.com>
     [not found]                                                     ` <20050209.151938.63052333.taka@valinux.co.jp>
2005-02-09 20:48                                                       ` Ray Bryant
2005-02-07 13:16                                     ` Hirokazu Takahashi
2005-02-03  2:49                               ` Hirokazu Takahashi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox