linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/7] page migration: Reorder functions in migrate.c
@ 2006-04-28  6:03 Christoph Lameter
  2006-04-28  6:03 ` [PATCH 2/7] page migration: Remove unnecessarily exported functions Christoph Lameter
                   ` (6 more replies)
  0 siblings, 7 replies; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28  6:03 UTC (permalink / raw)
  To: akpm
  Cc: linux-mm, KAMEZAWA Hiroyuki, Lee Schermerhorn, Christoph Lameter,
	Hugh Dickins

page migration: Reorder functions in migrate.c

Build a group of migration functions that can be used for
struct address_operations.

Group remove_migration_pte() and remove_migration_ptes() together.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-27 19:24:03.576736398 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-27 19:28:57.347549552 -0700
@@ -177,6 +177,37 @@
 }
 
 /*
+ * Get rid of all migration entries and replace them by
+ * references to the indicated page.
+ *
+ * Must hold mmap_sem lock on at least one of the vmas containing
+ * the page so that the anon_vma cannot vanish.
+ */
+static void remove_migration_ptes(struct page *old, struct page *new)
+{
+	struct anon_vma *anon_vma;
+	struct vm_area_struct *vma;
+	unsigned long mapping;
+
+	mapping = (unsigned long)new->mapping;
+
+	if (!mapping || (mapping & PAGE_MAPPING_ANON) == 0)
+		return;
+
+	/*
+	 * We hold the mmap_sem lock. So no need to call page_lock_anon_vma.
+	 */
+	anon_vma = (struct anon_vma *) (mapping - PAGE_MAPPING_ANON);
+	spin_lock(&anon_vma->lock);
+
+	list_for_each_entry(vma, &anon_vma->head, anon_vma_node)
+		remove_migration_pte(vma, page_address_in_vma(new, vma),
+					old, new);
+
+	spin_unlock(&anon_vma->lock);
+}
+
+/*
  * Something used the pte of a page under migration. We need to
  * get to the page and wait until migration is finished.
  * When we return from this function the fault will be retried.
@@ -215,46 +246,6 @@
 }
 
 /*
- * Get rid of all migration entries and replace them by
- * references to the indicated page.
- *
- * Must hold mmap_sem lock on at least one of the vmas containing
- * the page so that the anon_vma cannot vanish.
- */
-static void remove_migration_ptes(struct page *old, struct page *new)
-{
-	struct anon_vma *anon_vma;
-	struct vm_area_struct *vma;
-	unsigned long mapping;
-
-	mapping = (unsigned long)new->mapping;
-
-	if (!mapping || (mapping & PAGE_MAPPING_ANON) == 0)
-		return;
-
-	/*
-	 * We hold the mmap_sem lock. So no need to call page_lock_anon_vma.
-	 */
-	anon_vma = (struct anon_vma *) (mapping - PAGE_MAPPING_ANON);
-	spin_lock(&anon_vma->lock);
-
-	list_for_each_entry(vma, &anon_vma->head, anon_vma_node)
-		remove_migration_pte(vma, page_address_in_vma(new, vma),
-					old, new);
-
-	spin_unlock(&anon_vma->lock);
-}
-
-/*
- * Non migratable page
- */
-int fail_migrate_page(struct page *newpage, struct page *page)
-{
-	return -EIO;
-}
-EXPORT_SYMBOL(fail_migrate_page);
-
-/*
  * Remove or replace all references to a page so that future accesses to
  * the page can be blocked. Establish the new page
  * with the basic settings to be able to stop accesses to the page.
@@ -396,11 +387,18 @@
 }
 EXPORT_SYMBOL(migrate_page_copy);
 
+/************************************************************
+ *                    Migration functions
+ ***********************************************************/
+
+int fail_migrate_page(struct page *newpage, struct page *page)
+{
+	return -EIO;
+}
+EXPORT_SYMBOL(fail_migrate_page);
+
 /*
- * Common logic to directly migrate a single page suitable for
- * pages that do not use PagePrivate.
- *
- * Pages are locked upon entry and exit.
+ * migrate a page that does not use PagePrivate.
  */
 int migrate_page(struct page *newpage, struct page *page)
 {
@@ -423,6 +421,67 @@
 EXPORT_SYMBOL(migrate_page);
 
 /*
+ * Migration function for pages with buffers. This function can only be used
+ * if the underlying filesystem guarantees that no other references to "page"
+ * exist.
+ */
+int buffer_migrate_page(struct page *newpage, struct page *page)
+{
+	struct address_space *mapping = page->mapping;
+	struct buffer_head *bh, *head;
+	int rc;
+
+	if (!mapping)
+		return -EAGAIN;
+
+	if (!page_has_buffers(page))
+		return migrate_page(newpage, page);
+
+	head = page_buffers(page);
+
+	rc = migrate_page_remove_references(newpage, page, 3);
+
+	if (rc)
+		return rc;
+
+	bh = head;
+	do {
+		get_bh(bh);
+		lock_buffer(bh);
+		bh = bh->b_this_page;
+
+	} while (bh != head);
+
+	ClearPagePrivate(page);
+	set_page_private(newpage, page_private(page));
+	set_page_private(page, 0);
+	put_page(page);
+	get_page(newpage);
+
+	bh = head;
+	do {
+		set_bh_page(bh, newpage, bh_offset(bh));
+		bh = bh->b_this_page;
+
+	} while (bh != head);
+
+	SetPagePrivate(newpage);
+
+	migrate_page_copy(newpage, page);
+
+	bh = head;
+	do {
+		unlock_buffer(bh);
+ 		put_bh(bh);
+		bh = bh->b_this_page;
+
+	} while (bh != head);
+
+	return 0;
+}
+EXPORT_SYMBOL(buffer_migrate_page);
+
+/*
  * migrate_pages
  *
  * Two lists are passed to this function. The first list
@@ -577,67 +636,6 @@
 }
 
 /*
- * Migration function for pages with buffers. This function can only be used
- * if the underlying filesystem guarantees that no other references to "page"
- * exist.
- */
-int buffer_migrate_page(struct page *newpage, struct page *page)
-{
-	struct address_space *mapping = page->mapping;
-	struct buffer_head *bh, *head;
-	int rc;
-
-	if (!mapping)
-		return -EAGAIN;
-
-	if (!page_has_buffers(page))
-		return migrate_page(newpage, page);
-
-	head = page_buffers(page);
-
-	rc = migrate_page_remove_references(newpage, page, 3);
-
-	if (rc)
-		return rc;
-
-	bh = head;
-	do {
-		get_bh(bh);
-		lock_buffer(bh);
-		bh = bh->b_this_page;
-
-	} while (bh != head);
-
-	ClearPagePrivate(page);
-	set_page_private(newpage, page_private(page));
-	set_page_private(page, 0);
-	put_page(page);
-	get_page(newpage);
-
-	bh = head;
-	do {
-		set_bh_page(bh, newpage, bh_offset(bh));
-		bh = bh->b_this_page;
-
-	} while (bh != head);
-
-	SetPagePrivate(newpage);
-
-	migrate_page_copy(newpage, page);
-
-	bh = head;
-	do {
-		unlock_buffer(bh);
- 		put_bh(bh);
-		bh = bh->b_this_page;
-
-	} while (bh != head);
-
-	return 0;
-}
-EXPORT_SYMBOL(buffer_migrate_page);
-
-/*
  * Migrate the list 'pagelist' of pages to a certain destination.
  *
  * Specify destination with either non-NULL vma or dest_node >= 0

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 2/7] page migration: Remove unnecessarily exported functions
  2006-04-28  6:03 [PATCH 1/7] page migration: Reorder functions in migrate.c Christoph Lameter
@ 2006-04-28  6:03 ` Christoph Lameter
  2006-04-28  6:03 ` [PATCH 3/7] page migration: Change handling of address spaces Christoph Lameter
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28  6:03 UTC (permalink / raw)
  To: akpm
  Cc: linux-mm, Hugh Dickins, Lee Schermerhorn, Christoph Lameter,
	KAMEZAWA Hiroyuki

page migration: Remove unnecessarily exported functions

Remove the export for migrate_page_remove_references() and
migrate_page_copy() that are unlikely to be used directly by
filesystems implementing migration. The export was useful
when buffer_migrate_page() lived in fs/buffer.c but it has now
been moved to migrate.c in the migration reorg.

Signed-off-by: Christoph Lameter <clameter@sgi.com>


Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-27 19:28:57.347549552 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-27 19:34:41.194349304 -0700
@@ -250,7 +250,7 @@
  * the page can be blocked. Establish the new page
  * with the basic settings to be able to stop accesses to the page.
  */
-int migrate_page_remove_references(struct page *newpage,
+static int migrate_page_remove_references(struct page *newpage,
 				struct page *page, int nr_refs)
 {
 	struct address_space *mapping = page_mapping(page);
@@ -343,12 +343,11 @@
 
 	return 0;
 }
-EXPORT_SYMBOL(migrate_page_remove_references);
 
 /*
  * Copy the page to its new location
  */
-void migrate_page_copy(struct page *newpage, struct page *page)
+static void migrate_page_copy(struct page *newpage, struct page *page)
 {
 	copy_highpage(newpage, page);
 
@@ -385,7 +384,6 @@
 	if (PageWriteback(newpage))
 		end_page_writeback(newpage);
 }
-EXPORT_SYMBOL(migrate_page_copy);
 
 /************************************************************
  *                    Migration functions
Index: linux-2.6.17-rc2-mm1/include/linux/migrate.h
===================================================================
--- linux-2.6.17-rc2-mm1.orig/include/linux/migrate.h	2006-04-18 20:00:49.000000000 -0700
+++ linux-2.6.17-rc2-mm1/include/linux/migrate.h	2006-04-27 19:35:10.943477554 -0700
@@ -8,8 +8,6 @@
 extern int isolate_lru_page(struct page *p, struct list_head *pagelist);
 extern int putback_lru_pages(struct list_head *l);
 extern int migrate_page(struct page *, struct page *);
-extern void migrate_page_copy(struct page *, struct page *);
-extern int migrate_page_remove_references(struct page *, struct page *, int);
 extern int migrate_pages(struct list_head *l, struct list_head *t,
 		struct list_head *moved, struct list_head *failed);
 extern int migrate_pages_to(struct list_head *pagelist,

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 3/7] page migration: Change handling of address spaces
  2006-04-28  6:03 [PATCH 1/7] page migration: Reorder functions in migrate.c Christoph Lameter
  2006-04-28  6:03 ` [PATCH 2/7] page migration: Remove unnecessarily exported functions Christoph Lameter
@ 2006-04-28  6:03 ` Christoph Lameter
  2006-04-28  6:03 ` [PATCH 4/7] page migration: Drop nr_refs parameter Christoph Lameter
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28  6:03 UTC (permalink / raw)
  To: akpm
  Cc: linux-mm, KAMEZAWA Hiroyuki, Lee Schermerhorn, Christoph Lameter,
	Hugh Dickins

page migration: Change handling of address spaces.

Pass a pointer to the address space in which the page is migrated
to all migration function. This avoids repeatedly having to retrieve
the address space pointer from the page and checking it for validity.
The old page mapping will change once migration has gone to a certain
step, so it is less confusing to have the pointer always available.

Move the handling the mapping and index for the new page into
migrate_pages() in order to have stable mappings early
during migration.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-27 21:11:49.278491812 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-27 21:32:18.134185419 -0700
@@ -250,10 +250,9 @@
  * the page can be blocked. Establish the new page
  * with the basic settings to be able to stop accesses to the page.
  */
-static int migrate_page_remove_references(struct page *newpage,
-				struct page *page, int nr_refs)
+static int migrate_page_remove_references(struct address_space *mapping,
+		struct page *newpage, struct page *page, int nr_refs)
 {
-	struct address_space *mapping = page_mapping(page);
 	struct page **radix_pointer;
 
 	/*
@@ -297,9 +296,6 @@
 		if (page_count(page) != nr_refs)
 			return -EAGAIN;
 
-		/* We are holding the only remaining reference */
-		newpage->index = page->index;
-		newpage->mapping = page->mapping;
 		return 0;
 	}
 
@@ -320,15 +316,8 @@
 
 	/*
 	 * Now we know that no one else is looking at the page.
-	 *
-	 * Certain minimal information about a page must be available
-	 * in order for other subsystems to properly handle the page if they
-	 * find it through the radix tree update before we are finished
-	 * copying the page.
 	 */
 	get_page(newpage);
-	newpage->index = page->index;
-	newpage->mapping = page->mapping;
 
 #ifdef CONFIG_SWAP
 	if (PageSwapCache(page)) {
@@ -389,7 +378,8 @@
  *                    Migration functions
  ***********************************************************/
 
-int fail_migrate_page(struct page *newpage, struct page *page)
+int fail_migrate_page(struct address_space *mapping,
+			struct page *newpage, struct page *page)
 {
 	return -EIO;
 }
@@ -398,14 +388,15 @@
 /*
  * migrate a page that does not use PagePrivate.
  */
-int migrate_page(struct page *newpage, struct page *page)
+int migrate_page(struct address_space *mapping,
+		struct page *newpage, struct page *page)
 {
 	int rc;
 
 	BUG_ON(PageWriteback(page));	/* Writeback must be complete */
 
-	rc = migrate_page_remove_references(newpage, page,
-			page_mapping(page) ? 2 : 1);
+	rc = migrate_page_remove_references(mapping, newpage, page,
+			mapping ? 2 : 1);
 
 	if (rc) {
 		remove_migration_ptes(page, page);
@@ -423,21 +414,18 @@
  * if the underlying filesystem guarantees that no other references to "page"
  * exist.
  */
-int buffer_migrate_page(struct page *newpage, struct page *page)
+int buffer_migrate_page(struct address_space *mapping,
+			struct page *newpage, struct page *page)
 {
-	struct address_space *mapping = page->mapping;
 	struct buffer_head *bh, *head;
 	int rc;
 
-	if (!mapping)
-		return -EAGAIN;
-
 	if (!page_has_buffers(page))
-		return migrate_page(newpage, page);
+		return migrate_page(mapping, newpage, page);
 
 	head = page_buffers(page);
 
-	rc = migrate_page_remove_references(newpage, page, 3);
+	rc = migrate_page_remove_references(mapping, newpage, page, 3);
 
 	if (rc)
 		return rc;
@@ -550,6 +538,9 @@
 
 		newpage = lru_to_page(to);
 		lock_page(newpage);
+		/* Prepare mapping for the new page.*/
+		newpage->index = page->index;
+		newpage->mapping = page->mapping;
 
 		/*
 		 * Pages are properly locked and writeback is complete.
@@ -557,7 +548,7 @@
 		 */
 		mapping = page_mapping(page);
 		if (!mapping) {
-			rc = migrate_page(newpage, page);
+			rc = migrate_page(mapping, newpage, page);
 			goto unlock_both;
 
 		} else
@@ -569,7 +560,8 @@
 			 * own migration function. This is the most common
 			 * path for page migration.
 			 */
-			rc = mapping->a_ops->migratepage(newpage, page);
+			rc = mapping->a_ops->migratepage(mapping,
+							newpage, page);
 			goto unlock_both;
                 }
 
@@ -599,7 +591,7 @@
 		 */
 		if (!page_has_buffers(page) ||
 		    try_to_release_page(page, GFP_KERNEL)) {
-			rc = migrate_page(newpage, page);
+			rc = migrate_page(mapping, newpage, page);
 			goto unlock_both;
 		}
 
@@ -610,12 +602,15 @@
 		unlock_page(page);
 
 next:
-		if (rc == -EAGAIN) {
-			retry++;
-		} else if (rc) {
-			/* Permanent failure */
-			list_move(&page->lru, failed);
-			nr_failed++;
+		if (rc) {
+			newpage->mapping = NULL;
+			if (rc == -EAGAIN)
+				retry++;
+			else {
+				/* Permanent failure */
+				list_move(&page->lru, failed);
+				nr_failed++;
+			}
 		} else {
 			if (newpage) {
 				/* Successful migration. Return page to LRU */
Index: linux-2.6.17-rc2-mm1/include/linux/fs.h
===================================================================
--- linux-2.6.17-rc2-mm1.orig/include/linux/fs.h	2006-04-27 19:24:02.006521419 -0700
+++ linux-2.6.17-rc2-mm1/include/linux/fs.h	2006-04-27 21:15:09.388268028 -0700
@@ -373,7 +373,8 @@
 	struct page* (*get_xip_page)(struct address_space *, sector_t,
 			int);
 	/* migrate the contents of a page to the specified target */
-	int (*migratepage) (struct page *, struct page *);
+	int (*migratepage) (struct address_space *,
+			struct page *, struct page *);
 };
 
 struct backing_dev_info;
@@ -1773,7 +1774,8 @@
 extern ssize_t simple_read_from_buffer(void __user *, size_t, loff_t *, const void *, size_t);
 
 #ifdef CONFIG_MIGRATION
-extern int buffer_migrate_page(struct page *, struct page *);
+extern int buffer_migrate_page(struct address_space *,
+				struct page *, struct page *);
 #else
 #define buffer_migrate_page NULL
 #endif
Index: linux-2.6.17-rc2-mm1/include/linux/migrate.h
===================================================================
--- linux-2.6.17-rc2-mm1.orig/include/linux/migrate.h	2006-04-27 21:11:49.389813099 -0700
+++ linux-2.6.17-rc2-mm1/include/linux/migrate.h	2006-04-27 21:15:09.389244530 -0700
@@ -7,12 +7,14 @@
 #ifdef CONFIG_MIGRATION
 extern int isolate_lru_page(struct page *p, struct list_head *pagelist);
 extern int putback_lru_pages(struct list_head *l);
-extern int migrate_page(struct page *, struct page *);
+extern int migrate_page(struct address_space *,
+			struct page *, struct page *);
 extern int migrate_pages(struct list_head *l, struct list_head *t,
 		struct list_head *moved, struct list_head *failed);
 extern int migrate_pages_to(struct list_head *pagelist,
 			struct vm_area_struct *vma, int dest);
-extern int fail_migrate_page(struct page *, struct page *);
+extern int fail_migrate_page(struct address_space *,
+			struct page *, struct page *);
 
 extern int migrate_prep(void);
 

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 4/7] page migration: Drop nr_refs parameter
  2006-04-28  6:03 [PATCH 1/7] page migration: Reorder functions in migrate.c Christoph Lameter
  2006-04-28  6:03 ` [PATCH 2/7] page migration: Remove unnecessarily exported functions Christoph Lameter
  2006-04-28  6:03 ` [PATCH 3/7] page migration: Change handling of address spaces Christoph Lameter
@ 2006-04-28  6:03 ` Christoph Lameter
  2006-04-28  7:30   ` KAMEZAWA Hiroyuki
  2006-04-28  6:03 ` [PATCH 5/7] page migration: synchronize from and to lists Christoph Lameter
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28  6:03 UTC (permalink / raw)
  To: akpm
  Cc: linux-mm, Hugh Dickins, Lee Schermerhorn, Christoph Lameter,
	KAMEZAWA Hiroyuki

page migration: Drop nr_refs parameter from migrate_page_remove_references()

The nr_refs parameter is not really useful since the number of remaining
references is always

1 for anonymous pages without a mapping
2 for pages with a mapping
3 for pages with a mapping and PagePrivate set.

Remove the early check for the number of references since we are
checking page_mapcount() anyways. Ultimately only the refcount
matters after the tree_lock has been obtained.

Signed-off-by: Christoph Lameter <clameter@sgi.coim>

Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-27 21:32:18.134185419 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-27 21:32:46.933165848 -0700
@@ -251,20 +251,11 @@
  * with the basic settings to be able to stop accesses to the page.
  */
 static int migrate_page_remove_references(struct address_space *mapping,
-		struct page *newpage, struct page *page, int nr_refs)
+		struct page *newpage, struct page *page)
 {
 	struct page **radix_pointer;
 
 	/*
-	 * Avoid doing any of the following work if the page count
-	 * indicates that the page is in use or truncate has removed
-	 * the page.
-	 */
-	if (!page->mapping ||
-		page_mapcount(page) + nr_refs != page_count(page))
-			return -EAGAIN;
-
-	/*
 	 * Establish migration ptes for anonymous pages or destroy pte
 	 * maps for files.
 	 *
@@ -293,7 +284,7 @@
 		 * removed the ptes. Now check if the kernel still has
 		 * pending references.
 		 */
-		if (page_count(page) != nr_refs)
+		if (page_count(page) != 1)
 			return -EAGAIN;
 
 		return 0;
@@ -308,7 +299,8 @@
 						&mapping->page_tree,
 						page_index(page));
 
-	if (!page_mapping(page) || page_count(page) != nr_refs ||
+	if (!page_mapping(page) ||
+			page_count(page) != 2 + !!PagePrivate(page) ||
 			*radix_pointer != page) {
 		write_unlock_irq(&mapping->tree_lock);
 		return -EAGAIN;
@@ -395,8 +387,7 @@
 
 	BUG_ON(PageWriteback(page));	/* Writeback must be complete */
 
-	rc = migrate_page_remove_references(mapping, newpage, page,
-			mapping ? 2 : 1);
+	rc = migrate_page_remove_references(mapping, newpage, page);
 
 	if (rc) {
 		remove_migration_ptes(page, page);
@@ -425,7 +416,7 @@
 
 	head = page_buffers(page);
 
-	rc = migrate_page_remove_references(mapping, newpage, page, 3);
+	rc = migrate_page_remove_references(mapping, newpage, page);
 
 	if (rc)
 		return rc;

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 5/7] page migration: synchronize from and to lists
  2006-04-28  6:03 [PATCH 1/7] page migration: Reorder functions in migrate.c Christoph Lameter
                   ` (2 preceding siblings ...)
  2006-04-28  6:03 ` [PATCH 4/7] page migration: Drop nr_refs parameter Christoph Lameter
@ 2006-04-28  6:03 ` Christoph Lameter
  2006-04-28  7:46   ` KAMEZAWA Hiroyuki
  2006-04-28  6:03 ` [PATCH 6/7] page migration: Extract try_to_unmap Christoph Lameter
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28  6:03 UTC (permalink / raw)
  To: akpm
  Cc: linux-mm, KAMEZAWA Hiroyuki, Lee Schermerhorn, Christoph Lameter,
	Hugh Dickins

page migration: synchronize from and to lists to migrate_pages()

Handle pages from the "from" and "to" lists in such a way that the nth page
from "from" is moved to the nth page from "to". That way page placement
for each page can be controlled separately.

Also do some cleanups by removing a useless test on "to" and
reformatting some if statements.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-27 21:32:46.933165848 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-27 21:32:50.417322988 -0700
@@ -466,6 +466,9 @@
  * The second list contains new pages that the pages isolated
  * can be moved to.
  *
+ * Pages in both lists have a 1-1 correspondence. The nth page
+ * on "from" will be moved to the nth page on "to".
+ *
  * The function returns after 10 attempts or if no pages
  * are movable anymore because to has become empty
  * or no retryable pages exist anymore.
@@ -500,7 +503,7 @@
 			/* page was freed from under us. So we are done. */
 			goto next;
 
-		if (to && list_empty(to))
+		if (list_empty(to))
 			break;
 
 		/*
@@ -522,10 +525,9 @@
 		 */
 		if (pass > 0)
 			wait_on_page_writeback(page);
-		else {
-			if (PageWriteback(page))
+
+		else if (PageWriteback(page))
 				goto unlock_page;
-		}
 
 		newpage = lru_to_page(to);
 		lock_page(newpage);
@@ -594,19 +596,25 @@
 
 next:
 		if (rc) {
-			newpage->mapping = NULL;
+			if (newpage) {
+				newpage->mapping = NULL;
+				list_move_tail(&newpage->lru, to);
+			}
+
 			if (rc == -EAGAIN)
+				/* Soft failure */
 				retry++;
+
 			else {
 				/* Permanent failure */
 				list_move(&page->lru, failed);
 				nr_failed++;
 			}
 		} else {
-			if (newpage) {
+			if (newpage)
 				/* Successful migration. Return page to LRU */
 				move_to_lru(newpage);
-			}
+
 			list_move(&page->lru, moved);
 		}
 	}

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 6/7] page migration: Extract try_to_unmap
  2006-04-28  6:03 [PATCH 1/7] page migration: Reorder functions in migrate.c Christoph Lameter
                   ` (3 preceding siblings ...)
  2006-04-28  6:03 ` [PATCH 5/7] page migration: synchronize from and to lists Christoph Lameter
@ 2006-04-28  6:03 ` Christoph Lameter
  2006-04-28  6:03 ` [PATCH 7/7] page migration: Add new fallback function Christoph Lameter
  2006-04-28 22:08 ` [PATCH 1/7] page migration: Reorder functions in migrate.c Andrew Morton
  6 siblings, 0 replies; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28  6:03 UTC (permalink / raw)
  To: akpm
  Cc: linux-mm, Hugh Dickins, Lee Schermerhorn, Christoph Lameter,
	KAMEZAWA Hiroyuki

page migration: Extract try_to_unmap and rename remove_references -> move_mapping

try_to_unmap may significantly change the page state by for example setting
the dirty bit. It is therefore best for each migration function to do
try_to_unmap on their own before examining the page state.

migrate_page_remove_references() will then only move the new page in
place of the old page in the mapping. Rename the function to
migrate_page_move_mapping().

Signed-off-by: Christoph Lameter <clameter@sgi.com>


Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-27 21:32:50.417322988 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-27 21:34:12.171976982 -0700
@@ -246,32 +246,14 @@
 }
 
 /*
- * Remove or replace all references to a page so that future accesses to
- * the page can be blocked. Establish the new page
- * with the basic settings to be able to stop accesses to the page.
+ * Remove or replace the page in the mapping
  */
-static int migrate_page_remove_references(struct address_space *mapping,
+static int migrate_page_move_mapping(struct address_space *mapping,
 		struct page *newpage, struct page *page)
 {
 	struct page **radix_pointer;
 
 	/*
-	 * Establish migration ptes for anonymous pages or destroy pte
-	 * maps for files.
-	 *
-	 * In order to reestablish file backed mappings the fault handlers
-	 * will take the radix tree_lock which may then be used to stop
-  	 * processses from accessing this page until the new page is ready.
-	 *
-	 * A process accessing via a migration pte (an anonymous page) will
-	 * take a page_lock on the old page which will block the process
-	 * until the migration attempt is complete.
-	 */
-	if (try_to_unmap(page, 1) == SWAP_FAIL)
-		/* A vma has VM_LOCKED set -> permanent failure */
-		return -EPERM;
-
-	/*
 	 * Retry if we were unable to remove all mappings.
 	 */
 	if (page_mapcount(page))
@@ -280,9 +262,6 @@
 	if (!mapping) {
 		/*
 		 * Anonymous page without swap mapping.
-		 * User space cannot access the page anymore since we
-		 * removed the ptes. Now check if the kernel still has
-		 * pending references.
 		 */
 		if (page_count(page) != 1)
 			return -EAGAIN;
@@ -387,7 +366,12 @@
 
 	BUG_ON(PageWriteback(page));	/* Writeback must be complete */
 
-	rc = migrate_page_remove_references(mapping, newpage, page);
+	if (try_to_unmap(page, 1) == SWAP_FAIL) {
+		remove_migration_ptes(page, page);
+		return -EPERM;
+	}
+
+	rc = migrate_page_move_mapping(mapping, newpage, page);
 
 	if (rc) {
 		remove_migration_ptes(page, page);
@@ -414,9 +398,12 @@
 	if (!page_has_buffers(page))
 		return migrate_page(mapping, newpage, page);
 
+	if (try_to_unmap(page, 1) == SWAP_FAIL)
+		return -EPERM;
+
 	head = page_buffers(page);
 
-	rc = migrate_page_remove_references(mapping, newpage, page);
+	rc = migrate_page_move_mapping(mapping, newpage, page);
 
 	if (rc)
 		return rc;

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 7/7] page migration: Add new fallback function
  2006-04-28  6:03 [PATCH 1/7] page migration: Reorder functions in migrate.c Christoph Lameter
                   ` (4 preceding siblings ...)
  2006-04-28  6:03 ` [PATCH 6/7] page migration: Extract try_to_unmap Christoph Lameter
@ 2006-04-28  6:03 ` Christoph Lameter
  2006-04-28  6:42   ` Christoph Lameter
  2006-04-28 22:08 ` [PATCH 1/7] page migration: Reorder functions in migrate.c Andrew Morton
  6 siblings, 1 reply; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28  6:03 UTC (permalink / raw)
  To: akpm
  Cc: linux-mm, KAMEZAWA Hiroyuki, Lee Schermerhorn, Christoph Lameter,
	Hugh Dickins

page migration: Add new fallback function that checks properly for dirty pages

Add a new migration function that checks for PageDirty after unmapping
the ptes. It then directly writes out the page without relying on pageout().

Add some logic to deal with writepage() potentially unlocking the page.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-27 21:34:12.171976982 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-27 22:52:35.363141399 -0700
@@ -24,6 +24,7 @@
 #include <linux/topology.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
+#include <linux/writeback.h>
 
 #include "internal.h"
 
@@ -445,6 +446,66 @@
 }
 EXPORT_SYMBOL(buffer_migrate_page);
 
+static int fallback_migrate_page(struct address_space *mapping,
+		struct page *newpage, struct page *page)
+{
+	int rc;
+
+	if (try_to_unmap(page, 1) == SWAP_FAIL)
+		/* A vma has VM_LOCKED set -> permanent failure */
+		return -EPERM;
+
+	/*
+	 * Removing the ptes may have dirtied the page
+	 */
+	if (PageDirty(page)) {
+		struct writeback_control wbc = {
+			.sync_mode = WB_SYNC_NONE,
+			.nr_to_write = 1,
+			.range_start = 0,
+			.range_end = LLONG_MAX,
+			.nonblocking = 1,
+			.for_reclaim = 1
+		};
+
+		if (!mapping->a_ops->writepage)
+			/* No write method for the address space */
+			return -EINVAL;
+
+		if (!clear_page_dirty_for_io(page))
+			/* Someone else already triggered a write */
+			return -EAGAIN;
+
+		if (mapping->a_ops->writepage(page, &wbc) < 0)
+			/* I/O Error writing */
+			return -EIO;
+
+		/*
+		 * Retry if writepage() removed the lock or the page
+		 * is still dirty or undergoing writeback.
+		 */
+		if (!PageLocked(page) ||
+			PageWriteback(page) || PageDirty(page))
+				return -EAGAIN;
+	}
+
+	/*
+	 * Buffers are managed in a filesystem specific way.
+	 * We must have no buffers or drop them.
+	 */
+	if (page_has_buffers(page) &&
+	    !try_to_release_page(page, GFP_KERNEL))
+		return -EAGAIN;
+
+	rc = migrate_page_move_mapping(mapping, newpage, page);
+
+	if (rc)
+		return rc;
+
+	migrate_page_copy(newpage, page);
+	return 0;
+}
+
 /*
  * migrate_pages
  *
@@ -527,59 +588,19 @@
 		 * Try to migrate the page.
 		 */
 		mapping = page_mapping(page);
-		if (!mapping) {
+		if (!mapping)
 			rc = migrate_page(mapping, newpage, page);
-			goto unlock_both;
 
-		} else
-		if (mapping->a_ops->migratepage) {
-			/*
-			 * Most pages have a mapping and most filesystems
-			 * should provide a migration function. Anonymous
-			 * pages are part of swap space which also has its
-			 * own migration function. This is the most common
-			 * path for page migration.
-			 */
+		else if (mapping->a_ops->migratepage)
 			rc = mapping->a_ops->migratepage(mapping,
 							newpage, page);
-			goto unlock_both;
-                }
-
-		/*
-		 * Default handling if a filesystem does not provide
-		 * a migration function. We can only migrate clean
-		 * pages so try to write out any dirty pages first.
-		 */
-		if (PageDirty(page)) {
-			switch (pageout(page, mapping)) {
-			case PAGE_KEEP:
-			case PAGE_ACTIVATE:
-				goto unlock_both;
-
-			case PAGE_SUCCESS:
-				unlock_page(newpage);
-				goto next;
-
-			case PAGE_CLEAN:
-				; /* try to migrate the page below */
-			}
-                }
-
-		/*
-		 * Buffers are managed in a filesystem specific way.
-		 * We must have no buffers or drop them.
-		 */
-		if (!page_has_buffers(page) ||
-		    try_to_release_page(page, GFP_KERNEL)) {
-			rc = migrate_page(mapping, newpage, page);
-			goto unlock_both;
-		}
+		else
+			rc = fallback_migrate_page(mapping, newpage, page);
 
-unlock_both:
 		unlock_page(newpage);
-
 unlock_page:
-		unlock_page(page);
+		if (PageLocked(page))	/* writepage() may unlock */
+			unlock_page(page);
 
 next:
 		if (rc) {

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 7/7] page migration: Add new fallback function
  2006-04-28  6:03 ` [PATCH 7/7] page migration: Add new fallback function Christoph Lameter
@ 2006-04-28  6:42   ` Christoph Lameter
  0 siblings, 0 replies; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28  6:42 UTC (permalink / raw)
  To: akpm; +Cc: linux-mm, KAMEZAWA Hiroyuki, Lee Schermerhorn, Hugh Dickins

Hmmm... We need to get rid of if(PageLocked())

This introduced another race condition since another process may have
locked the page. Simply relock the page after successfully calling
migratepages() and then retry.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-27 22:55:46.731119932 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-27 23:39:11.853319378 -0700
@@ -476,17 +476,20 @@
 			/* Someone else already triggered a write */
 			return -EAGAIN;
 
-		if (mapping->a_ops->writepage(page, &wbc) < 0)
+		rc = mapping->a_ops->writepage(page, &wbc);
+		if (rc < 0)
 			/* I/O Error writing */
 			return -EIO;
 
+		if (rc == AOP_WRITEPAGE_ACTIVATE)
+			return -EAGAIN;
+
+		lock_page(page);
 		/*
-		 * Retry if writepage() removed the lock or the page
-		 * is still dirty or undergoing writeback.
+		 * The lock was dropped by writepage() and so something
+		 * may have changed with the page.
 		 */
-		if (!PageLocked(page) ||
-			PageWriteback(page) || PageDirty(page))
-				return -EAGAIN;
+		return -EAGAIN;
 	}
 
 	/*
@@ -599,8 +602,7 @@
 
 		unlock_page(newpage);
 unlock_page:
-		if (PageLocked(page))	/* writepage() may unlock */
-			unlock_page(page);
+		unlock_page(page);
 
 next:
 		if (rc) {

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 4/7] page migration: Drop nr_refs parameter
  2006-04-28  6:03 ` [PATCH 4/7] page migration: Drop nr_refs parameter Christoph Lameter
@ 2006-04-28  7:30   ` KAMEZAWA Hiroyuki
  2006-04-28 13:57     ` Christoph Lameter
  0 siblings, 1 reply; 25+ messages in thread
From: KAMEZAWA Hiroyuki @ 2006-04-28  7:30 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: akpm, linux-mm, hugh, lee.schermerhorn

On Thu, 27 Apr 2006 23:03:18 -0700 (PDT)
Christoph Lameter <clameter@sgi.com> wrote:

> page migration: Drop nr_refs parameter from migrate_page_remove_references()
> 
> The nr_refs parameter is not really useful since the number of remaining
> references is always
> 
> 1 for anonymous pages without a mapping
> 2 for pages with a mapping
> 3 for pages with a mapping and PagePrivate set.
> 
Then, could you add this comment to migrate_page_remove_references
(renamed as migrate_page_move_mapping) ?

-Kame


--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 5/7] page migration: synchronize from and to lists
  2006-04-28  6:03 ` [PATCH 5/7] page migration: synchronize from and to lists Christoph Lameter
@ 2006-04-28  7:46   ` KAMEZAWA Hiroyuki
  2006-04-28 15:31     ` Christoph Lameter
  0 siblings, 1 reply; 25+ messages in thread
From: KAMEZAWA Hiroyuki @ 2006-04-28  7:46 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: akpm, linux-mm, lee.schermerhorn, hugh

On Thu, 27 Apr 2006 23:03:23 -0700 (PDT)
Christoph Lameter <clameter@sgi.com> wrote:

> page migration: synchronize from and to lists to migrate_pages()
> 
> Handle pages from the "from" and "to" lists in such a way that the nth page
> from "from" is moved to the nth page from "to". That way page placement
> for each page can be controlled separately.
> 
It looks this path is not treated in desired way.
==
		rc=0;
                if (page_count(page) == 1)
                        /* page was freed from under us. So we are done. */
                        goto next;
next:
                if (rc) {
			<snip>;
		} else {
			 if (newpage) <--- new page is NULL. here
                                /* Successful migration. Return page to LRU */
                                move_to_lru(newpage);

                        list_move(&page->lru, moved);
                }
==

you should rotate "to" list in this case, I think.		

Thanks,
-Kame

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 4/7] page migration: Drop nr_refs parameter
  2006-04-28  7:30   ` KAMEZAWA Hiroyuki
@ 2006-04-28 13:57     ` Christoph Lameter
  0 siblings, 0 replies; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28 13:57 UTC (permalink / raw)
  To: KAMEZAWA Hiroyuki; +Cc: akpm, linux-mm, hugh, lee.schermerhorn

On Fri, 28 Apr 2006, KAMEZAWA Hiroyuki wrote:

> Then, could you add this comment to migrate_page_remove_references
> (renamed as migrate_page_move_mapping) ?

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-27 23:39:11.853319378 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-28 06:56:36.856624280 -0700
@@ -248,6 +248,11 @@
 
 /*
  * Remove or replace the page in the mapping
+ *
+ * The number of remaining references must be:
+ * 1 for anonymous pages without a mapping
+ * 2 for pages with a mapping
+ * 3 for pages with a mapping and PagePrivate set.
  */
 static int migrate_page_move_mapping(struct address_space *mapping,
 		struct page *newpage, struct page *page)

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 5/7] page migration: synchronize from and to lists
  2006-04-28  7:46   ` KAMEZAWA Hiroyuki
@ 2006-04-28 15:31     ` Christoph Lameter
  2006-04-29  0:27       ` KAMEZAWA Hiroyuki
  0 siblings, 1 reply; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28 15:31 UTC (permalink / raw)
  To: KAMEZAWA Hiroyuki; +Cc: akpm, linux-mm, lee.schermerhorn, hugh

On Fri, 28 Apr 2006, KAMEZAWA Hiroyuki wrote:

> you should rotate "to" list in this case, I think.		

Hmmm.... Seems that the whole list scanning needs an overhaul. What do 
you thinkg about this?


Rework main loop in migrate_pages()

Take pages off the "to" and "from" list in a consistent way so that 1-1
relationships between pages on both lists can be maintained.

This also means that pages are not on any list while migration is attempted.
Instead of "move_to_lru" we only need "to_lru".

Index: linux-2.6.17-rc2-mm1/mm/migrate.c
===================================================================
--- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-28 06:56:36.856624280 -0700
+++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-28 08:26:29.893711598 -0700
@@ -82,9 +82,8 @@
 	return 0;
 }
 
-static inline void move_to_lru(struct page *page)
+static inline void to_lru(struct page *page)
 {
-	list_del(&page->lru);
 	if (PageActive(page)) {
 		/*
 		 * lru_cache_add_active checks that
@@ -92,9 +91,9 @@
 		 */
 		ClearPageActive(page);
 		lru_cache_add_active(page);
-	} else {
+	} else
 		lru_cache_add(page);
-	}
+
 	put_page(page);
 }
 
@@ -110,7 +109,8 @@
 	int count = 0;
 
 	list_for_each_entry_safe(page, page2, l, lru) {
-		move_to_lru(page);
+		list_del(&page->lru);
+		to_lru(page);
 		count++;
 	}
 	return count;
@@ -532,36 +532,42 @@
  * Return: Number of pages not migrated when "to" ran empty.
  */
 int migrate_pages(struct list_head *from, struct list_head *to,
-		  struct list_head *moved, struct list_head *failed)
+		  struct list_head *done, struct list_head *failed)
 {
-	int retry;
 	int nr_failed = 0;
 	int pass = 0;
-	struct page *page;
-	struct page *page2;
 	int swapwrite = current->flags & PF_SWAPWRITE;
-	int rc;
+	int retry;
+	struct list_head retry_to;
+	struct list_head retry_from;
+	struct list_head unused;
 
 	if (!swapwrite)
 		current->flags |= PF_SWAPWRITE;
 
+	INIT_LIST_HEAD(&unused);
 redo:
 	retry = 0;
+	INIT_LIST_HEAD(&retry_from);
+	INIT_LIST_HEAD(&retry_to);
 
-	list_for_each_entry_safe(page, page2, from, lru) {
-		struct page *newpage = NULL;
+	while (!list_empty(from) && !list_empty(to)) {
+		int rc = 0;
+		struct page *page;
+		struct page *newpage;
 		struct address_space *mapping;
 
 		cond_resched();
 
-		rc = 0;
+		page = lru_to_page(from);
+		list_del(&page->lru);
+		newpage = lru_to_page(to);
+		list_del(&newpage->lru);
+
 		if (page_count(page) == 1)
 			/* page was freed from under us. So we are done. */
 			goto next;
 
-		if (list_empty(to))
-			break;
-
 		/*
 		 * Skip locked pages during the first two passes to give the
 		 * functions holding the lock time to release the page. Later we
@@ -585,7 +591,6 @@
 		else if (PageWriteback(page))
 				goto unlock_page;
 
-		newpage = lru_to_page(to);
 		lock_page(newpage);
 		/* Prepare mapping for the new page.*/
 		newpage->index = page->index;
@@ -610,32 +615,33 @@
 		unlock_page(page);
 
 next:
-		if (rc) {
-			if (newpage) {
-				newpage->mapping = NULL;
-				list_move_tail(&newpage->lru, to);
-			}
+		if (likely(rc == 0)) {
+			/* Successful migration. */
+			to_lru(newpage);
+			list_add(&page->lru, done);
+		} else {
 
-			if (rc == -EAGAIN)
+			newpage->mapping = NULL;
+			if (rc == -EAGAIN) {
 				/* Soft failure */
 				retry++;
-
-			else {
+				list_add(&newpage->lru, &retry_to);
+				list_add(&page->lru, &retry_from);
+			} else {
 				/* Permanent failure */
-				list_move(&page->lru, failed);
 				nr_failed++;
+				list_add(&newpage->lru, &unused);
+				list_add(&page->lru, failed);
 			}
-		} else {
-			if (newpage)
-				/* Successful migration. Return page to LRU */
-				move_to_lru(newpage);
-
-			list_move(&page->lru, moved);
 		}
 	}
+	list_splice(&retry_to, to);
+	list_splice(&retry_from, from);
+
 	if (retry && pass++ < 10)
 		goto redo;
 
+	list_splice(&unused, to);
 	if (!swapwrite)
 		current->flags &= ~PF_SWAPWRITE;
 

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/7] page migration: Reorder functions in migrate.c
  2006-04-28  6:03 [PATCH 1/7] page migration: Reorder functions in migrate.c Christoph Lameter
                   ` (5 preceding siblings ...)
  2006-04-28  6:03 ` [PATCH 7/7] page migration: Add new fallback function Christoph Lameter
@ 2006-04-28 22:08 ` Andrew Morton
  2006-04-28 23:01   ` Christoph Lameter
  6 siblings, 1 reply; 25+ messages in thread
From: Andrew Morton @ 2006-04-28 22:08 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-mm, kamezawa.hiroyu, lee.schermerhorn, hugh

Christoph Lameter <clameter@sgi.com> wrote:
>
> page migration: Reorder functions in migrate.c

I'm a bit concerned about the way these migration patches are shaping up.

- There was quite a lot of rework against the initial batch of "swapless"
  patches.  I haven't yet found the time to sit down and review the end
  result.

- The initial batch of "swapless" patches needed a whole barrage of
  fixups to make the kernel compile.

- The patch series is rather straggly now: later patches are fixing up
  code which was added in multiple earlier patches, so refactoring it all
  logically is non-trivial.

- I have vague feelings of disquiet regarding the whole thing and would
  like to find the time to sit down and take a closer look at what's going
  on in there.  This is a bit hard with the patches factored as they are
  now.

So I'm thinking it'd be good (for me, at least) if I were to drop the lot
and ask you to refactor the patch series back into a logical sequence, make
sure all the fixups are folded into the right places so we can generally
take a fresh look at what you're proposing.

How hurtful would that be?

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/7] page migration: Reorder functions in migrate.c
  2006-04-28 22:08 ` [PATCH 1/7] page migration: Reorder functions in migrate.c Andrew Morton
@ 2006-04-28 23:01   ` Christoph Lameter
  2006-04-28 23:18     ` Andrew Morton
  0 siblings, 1 reply; 25+ messages in thread
From: Christoph Lameter @ 2006-04-28 23:01 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mm, kamezawa.hiroyu, lee.schermerhorn, hugh

On Fri, 28 Apr 2006, Andrew Morton wrote:
> I'm a bit concerned about the way these migration patches are shaping up.
> 
> - There was quite a lot of rework against the initial batch of "swapless"
>   patches.  I haven't yet found the time to sit down and review the end
>   result.
> 
> - The initial batch of "swapless" patches needed a whole barrage of
>   fixups to make the kernel compile.

The barrage came in because there was additional functionality proposed. 
The read/write entry support incomplete and required additional code 
to fix paths that may touch locked pages. If this functionality is too 
problematic then the read/write support could be dropped.

> - The patch series is rather straggly now: later patches are fixing up
>   code which was added in multiple earlier patches, so refactoring it all
>   logically is non-trivial.

Hmm... Yes there is quite a bit that accumulated. There are a number of 
patches that were done in order to reorganize the code.
 
> - I have vague feelings of disquiet regarding the whole thing and would
>   like to find the time to sit down and take a closer look at what's going
>   on in there.  This is a bit hard with the patches factored as they are
>   now.

> So I'm thinking it'd be good (for me, at least) if I were to drop the lot
> and ask you to refactor the patch series back into a logical sequence, make
> sure all the fixups are folded into the right places so we can generally
> take a fresh look at what you're proposing.
> 
> How hurtful would that be?

Not too difficult if I have a tree to patch against.

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/7] page migration: Reorder functions in migrate.c
  2006-04-28 23:01   ` Christoph Lameter
@ 2006-04-28 23:18     ` Andrew Morton
  2006-04-29  0:14       ` Christoph Lameter
  0 siblings, 1 reply; 25+ messages in thread
From: Andrew Morton @ 2006-04-28 23:18 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-mm, kamezawa.hiroyu, lee.schermerhorn, hugh

Christoph Lameter <clameter@sgi.com> wrote:
>
> > How hurtful would that be?
> 
> Not too difficult if I have a tree to patch against.

OK, thanks.

Patches against mainline would probably suit - I don't think there's much
overlapping stuff going on, if any.

http://www.zip.com.au/~akpm/linux/patches/stuff/x.bz2 is my current rollup
(against -rc3) up to the end of the memory management stuff (ie: where I'll
insert the new migration patches).  So perhaps you could verify that the
reworked patches apply against that patch, at least.

It includes:

mm-vm_bug_on.patch
mm-thrash-detect-process-thrashing-against-itself.patch
#mm-posix-memory-lock.patch
page-migration-make-do_swap_page-redo-the-fault.patch
slab-extract-cache_free_alien-from-__cache_free.patch
pg_uncached-is-ia64-only.patch
slab-page-mapping-cleanup.patch
migration-remove-unnecessary-pageswapcache-checks.patch
wait_table-and-zonelist-initializing-for-memory-hotadd-change-name-of-wait_table_size.patch
wait_table-and-zonelist-initializing-for-memory-hotadd-change-to-meminit-for-build_zonelist.patch
wait_table-and-zonelist-initializing-for-memory-hotaddadd-return-code-for-init_current_empty_zone.patch
wait_table-and-zonelist-initializing-for-memory-hotadd-wait_table-initialization.patch
wait_table-and-zonelist-initializing-for-memory-hotadd-update-zonelists.patch
squash-duplicate-page_to_pfn-and-pfn_to_page.patch
sparsemem-interaction-with-memory-add-bug-fixes.patch
support-for-panic-at-oom.patch
mm-fix-typos-in-comments-in-mm-oom_killc.patch
reserve-space-for-swap-label.patch
tightening-hugetlb-strict-accounting.patch
slab-cleanup-kmem_getpages.patch
slab-stop-using-list_for_each.patch
swsusp-rework-memory-shrinker-rev-2.patch
swsusp-rework-memory-shrinker-rev-2-fix.patch
#
pgdat-allocation-for-new-node-add-specify-node-id.patch
pgdat-allocation-for-new-node-add-specify-node-id-powerpc-fix.patch
pgdat-allocation-for-new-node-add-specify-node-id-tidy.patch
pgdat-allocation-for-new-node-add-specify-node-id-fix-3.patch
pgdat-allocation-for-new-node-add-get-node-id-by-acpi.patch
pgdat-allocation-for-new-node-add-get-node-id-by-acpi-tidy.patch
pgdat-allocation-for-new-node-add-generic-alloc-node_data.patch
pgdat-allocation-for-new-node-add-generic-alloc-node_data-tidy.patch
pgdat-allocation-for-new-node-add-refresh-node_data.patch
pgdat-allocation-for-new-node-add-refresh-node_data-fix.patch
pgdat-allocation-for-new-node-add-export-kswapd-start-func.patch
pgdat-allocation-for-new-node-add-export-kswapd-start-func-tidy.patch
pgdat-allocation-for-new-node-add-call-pgdat-allocation.patch
register-hot-added-memory-to-iomem-resource.patch
#
mm-introduce-remap_vmalloc_range.patch
mm-introduce-remap_vmalloc_range-tidy.patch
mm-introduce-remap_vmalloc_range-fix.patch
#
change-gen_pool-allocator-to-not-touch-managed-memory.patch
change-gen_pool-allocator-to-not-touch-managed-memory-update.patch
change-gen_pool-allocator-to-not-touch-managed-memory-update-2.patch
radix-tree-direct-data.patch
radix-tree-small.patch
likely-cleanup-remove-unlikely-in-sys_mprotect.patch
slab-redzone-double-free-detection.patch

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/7] page migration: Reorder functions in migrate.c
  2006-04-28 23:18     ` Andrew Morton
@ 2006-04-29  0:14       ` Christoph Lameter
  2006-04-29  0:36         ` Andrew Morton
  0 siblings, 1 reply; 25+ messages in thread
From: Christoph Lameter @ 2006-04-29  0:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mm, kamezawa.hiroyu, lee.schermerhorn, hugh

On Fri, 28 Apr 2006, Andrew Morton wrote:

> Patches against mainline would probably suit - I don't think there's much
> overlapping stuff going on, if any.

Ok. Here is the most important fix that also needs to go into 2.6.17. The 
rest will follow:


page migration: Fix fallback behavior for dirty pages.

Currently we check PageDirty() in order to make the decision to
swap out the page. However, the dirty information may be only be
contained in the ptes pointing to the page. We need to first unmap
the ptes before checking for PageDirty(). If unmap is successful then
the page count of the page will also be decreased so that pageout() works
properly.

This is a fix necessary for 2.6.17. Without this fix we may migrate
dirty pages for filesystems without migration functions. Filesystems
may keep pointers to dirty pages. Migration of dirty pages can
result in the filesystem keeping pointers to freed pages.

Unmapping is currently not be separated out from removing all the
references to a page and moving the mapping. Therefore try_to_unmap will
be called again in migrate_page() if the writeout is successful. However,
it wont do anything since the ptes are already removed.

The coming updates to the page migration code will restructure the code
so that this is no longer necessary.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.17-rc3/mm/migrate.c
===================================================================
--- linux-2.6.17-rc3.orig/mm/migrate.c	2006-04-26 19:19:25.000000000 -0700
+++ linux-2.6.17-rc3/mm/migrate.c	2006-04-28 17:11:42.779439413 -0700
@@ -439,6 +439,17 @@
 			goto unlock_both;
                 }
 
+		/* Make sure the dirty bit is up to date */
+		if (try_to_unmap(page, 1) == SWAP_FAIL) {
+			rc = -EPERM;
+			goto unlock_both;
+		}
+
+		if (page_mapcount(page)) {
+			rc = -EAGAIN;
+			goto unlock_both;
+		}
+
 		/*
 		 * Default handling if a filesystem does not provide
 		 * a migration function. We can only migrate clean

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 5/7] page migration: synchronize from and to lists
  2006-04-28 15:31     ` Christoph Lameter
@ 2006-04-29  0:27       ` KAMEZAWA Hiroyuki
  2006-04-29  0:33         ` Christoph Lameter
  0 siblings, 1 reply; 25+ messages in thread
From: KAMEZAWA Hiroyuki @ 2006-04-29  0:27 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: akpm, linux-mm, lee.schermerhorn, hugh

On Fri, 28 Apr 2006 08:31:04 -0700 (PDT)
Christoph Lameter <clameter@sgi.com> wrote:

> On Fri, 28 Apr 2006, KAMEZAWA Hiroyuki wrote:
> 
> > you should rotate "to" list in this case, I think.		
> 
> Hmmm.... Seems that the whole list scanning needs an overhaul. What do 
> you thinkg about this?
> 
maybe work, but complicated..
What benefits by this 1-1 ordering ?


-Kame


> 
> Rework main loop in migrate_pages()
> 
> Take pages off the "to" and "from" list in a consistent way so that 1-1
> relationships between pages on both lists can be maintained.
> 
> This also means that pages are not on any list while migration is attempted.
> Instead of "move_to_lru" we only need "to_lru".
> 
> Index: linux-2.6.17-rc2-mm1/mm/migrate.c
> ===================================================================
> --- linux-2.6.17-rc2-mm1.orig/mm/migrate.c	2006-04-28 06:56:36.856624280 -0700
> +++ linux-2.6.17-rc2-mm1/mm/migrate.c	2006-04-28 08:26:29.893711598 -0700
> @@ -82,9 +82,8 @@
>  	return 0;
>  }
>  
> -static inline void move_to_lru(struct page *page)
> +static inline void to_lru(struct page *page)
>  {
> -	list_del(&page->lru);
>  	if (PageActive(page)) {
>  		/*
>  		 * lru_cache_add_active checks that
> @@ -92,9 +91,9 @@
>  		 */
>  		ClearPageActive(page);
>  		lru_cache_add_active(page);
> -	} else {
> +	} else
>  		lru_cache_add(page);
> -	}
> +
>  	put_page(page);
>  }
>  
> @@ -110,7 +109,8 @@
>  	int count = 0;
>  
>  	list_for_each_entry_safe(page, page2, l, lru) {
> -		move_to_lru(page);
> +		list_del(&page->lru);
> +		to_lru(page);
>  		count++;
>  	}
>  	return count;
> @@ -532,36 +532,42 @@
>   * Return: Number of pages not migrated when "to" ran empty.
>   */
>  int migrate_pages(struct list_head *from, struct list_head *to,
> -		  struct list_head *moved, struct list_head *failed)
> +		  struct list_head *done, struct list_head *failed)
>  {
> -	int retry;
>  	int nr_failed = 0;
>  	int pass = 0;
> -	struct page *page;
> -	struct page *page2;
>  	int swapwrite = current->flags & PF_SWAPWRITE;
> -	int rc;
> +	int retry;
> +	struct list_head retry_to;
> +	struct list_head retry_from;
> +	struct list_head unused;
>  
>  	if (!swapwrite)
>  		current->flags |= PF_SWAPWRITE;
>  
> +	INIT_LIST_HEAD(&unused);
>  redo:
>  	retry = 0;
> +	INIT_LIST_HEAD(&retry_from);
> +	INIT_LIST_HEAD(&retry_to);
>  
> -	list_for_each_entry_safe(page, page2, from, lru) {
> -		struct page *newpage = NULL;
> +	while (!list_empty(from) && !list_empty(to)) {
> +		int rc = 0;
> +		struct page *page;
> +		struct page *newpage;
>  		struct address_space *mapping;
>  
>  		cond_resched();
>  
> -		rc = 0;
> +		page = lru_to_page(from);
> +		list_del(&page->lru);
> +		newpage = lru_to_page(to);
> +		list_del(&newpage->lru);
> +
>  		if (page_count(page) == 1)
>  			/* page was freed from under us. So we are done. */
>  			goto next;
>  
> -		if (list_empty(to))
> -			break;
> -
>  		/*
>  		 * Skip locked pages during the first two passes to give the
>  		 * functions holding the lock time to release the page. Later we
> @@ -585,7 +591,6 @@
>  		else if (PageWriteback(page))
>  				goto unlock_page;
>  
> -		newpage = lru_to_page(to);
>  		lock_page(newpage);
>  		/* Prepare mapping for the new page.*/
>  		newpage->index = page->index;
> @@ -610,32 +615,33 @@
>  		unlock_page(page);
>  
>  next:
> -		if (rc) {
> -			if (newpage) {
> -				newpage->mapping = NULL;
> -				list_move_tail(&newpage->lru, to);
> -			}
> +		if (likely(rc == 0)) {
> +			/* Successful migration. */
> +			to_lru(newpage);
> +			list_add(&page->lru, done);
> +		} else {
>  
> -			if (rc == -EAGAIN)
> +			newpage->mapping = NULL;
> +			if (rc == -EAGAIN) {
>  				/* Soft failure */
>  				retry++;
> -
> -			else {
> +				list_add(&newpage->lru, &retry_to);
> +				list_add(&page->lru, &retry_from);
> +			} else {
>  				/* Permanent failure */
> -				list_move(&page->lru, failed);
>  				nr_failed++;
> +				list_add(&newpage->lru, &unused);
> +				list_add(&page->lru, failed);
>  			}
> -		} else {
> -			if (newpage)
> -				/* Successful migration. Return page to LRU */
> -				move_to_lru(newpage);
> -
> -			list_move(&page->lru, moved);
>  		}
>  	}
> +	list_splice(&retry_to, to);
> +	list_splice(&retry_from, from);
> +
>  	if (retry && pass++ < 10)
>  		goto redo;
>  
> +	list_splice(&unused, to);
>  	if (!swapwrite)
>  		current->flags &= ~PF_SWAPWRITE;
>  
> 

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 5/7] page migration: synchronize from and to lists
  2006-04-29  0:27       ` KAMEZAWA Hiroyuki
@ 2006-04-29  0:33         ` Christoph Lameter
  2006-04-29  0:44           ` KAMEZAWA Hiroyuki
  0 siblings, 1 reply; 25+ messages in thread
From: Christoph Lameter @ 2006-04-29  0:33 UTC (permalink / raw)
  To: KAMEZAWA Hiroyuki; +Cc: akpm, linux-mm, lee.schermerhorn, hugh

On Sat, 29 Apr 2006, KAMEZAWA Hiroyuki wrote:

> On Fri, 28 Apr 2006 08:31:04 -0700 (PDT)
> Christoph Lameter <clameter@sgi.com> wrote:
> 
> > On Fri, 28 Apr 2006, KAMEZAWA Hiroyuki wrote:
> > 
> > > you should rotate "to" list in this case, I think.		
> > 
> > Hmmm.... Seems that the whole list scanning needs an overhaul. What do 
> > you thinkg about this?
> > 
> maybe work, but complicated..
> What benefits by this 1-1 ordering ?

You can control exactly where each page is migrated. Currently a page on 
from is migrated to some page on the to list.

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/7] page migration: Reorder functions in migrate.c
  2006-04-29  0:14       ` Christoph Lameter
@ 2006-04-29  0:36         ` Andrew Morton
  2006-04-29  0:46           ` Christoph Lameter
  2006-04-29  0:54           ` Christoph Lameter
  0 siblings, 2 replies; 25+ messages in thread
From: Andrew Morton @ 2006-04-29  0:36 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-mm, kamezawa.hiroyu, lee.schermerhorn, hugh

hm.  migrate_pages() locks two pages at the same time.  We've avoided doing
that.

a) what prevents ab/ba deadlocks in the migration code?

b) if some other part of the kernel later decides to lock two pages at
   the same time, what protocol should that code follow to avoid ab/ba
   deadlocks?   lowest-pfn-first might be one.

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 5/7] page migration: synchronize from and to lists
  2006-04-29  0:33         ` Christoph Lameter
@ 2006-04-29  0:44           ` KAMEZAWA Hiroyuki
  2006-04-29  0:46             ` Christoph Lameter
  0 siblings, 1 reply; 25+ messages in thread
From: KAMEZAWA Hiroyuki @ 2006-04-29  0:44 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: akpm, linux-mm, lee.schermerhorn, hugh

On Fri, 28 Apr 2006 17:33:22 -0700 (PDT)
Christoph Lameter <clameter@sgi.com> wrote:

> On Sat, 29 Apr 2006, KAMEZAWA Hiroyuki wrote:
> 
> > On Fri, 28 Apr 2006 08:31:04 -0700 (PDT)
> > Christoph Lameter <clameter@sgi.com> wrote:
> > 
> > > On Fri, 28 Apr 2006, KAMEZAWA Hiroyuki wrote:
> > > 
> > > > you should rotate "to" list in this case, I think.		
> > > 
> > > Hmmm.... Seems that the whole list scanning needs an overhaul. What do 
> > > you thinkg about this?
> > > 
> > maybe work, but complicated..
> > What benefits by this 1-1 ordering ?
> 
> You can control exactly where each page is migrated. Currently a page on 
> from is migrated to some page on the to list.
> 
Then, array is sane interface rather than list, I think.

-Kame

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/7] page migration: Reorder functions in migrate.c
  2006-04-29  0:36         ` Andrew Morton
@ 2006-04-29  0:46           ` Christoph Lameter
  2006-04-29  2:27             ` Andrew Morton
  2006-04-29  0:54           ` Christoph Lameter
  1 sibling, 1 reply; 25+ messages in thread
From: Christoph Lameter @ 2006-04-29  0:46 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mm, kamezawa.hiroyu, lee.schermerhorn, hugh

On Fri, 28 Apr 2006, Andrew Morton wrote:

> hm.  migrate_pages() locks two pages at the same time.  We've avoided doing
> that.
> 
> a) what prevents ab/ba deadlocks in the migration code?

Nothing right now.


> b) if some other part of the kernel later decides to lock two pages at
>    the same time, what protocol should that code follow to avoid ab/ba
>    deadlocks?   lowest-pfn-first might be one.

We could just do a TestSetPageLocked() on the newpage. If it fails then we 
postphone migration to the next loop. 

Patch on top of the one i just sent you or after the cleanup patches?

 

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 5/7] page migration: synchronize from and to lists
  2006-04-29  0:44           ` KAMEZAWA Hiroyuki
@ 2006-04-29  0:46             ` Christoph Lameter
  0 siblings, 0 replies; 25+ messages in thread
From: Christoph Lameter @ 2006-04-29  0:46 UTC (permalink / raw)
  To: KAMEZAWA Hiroyuki; +Cc: akpm, linux-mm, lee.schermerhorn, hugh

On Sat, 29 Apr 2006, KAMEZAWA Hiroyuki wrote:

> > You can control exactly where each page is migrated. Currently a page on 
> > from is migrated to some page on the to list.
> > 
> Then, array is sane interface rather than list, I think.

Hmmm. Good idea.

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/7] page migration: Reorder functions in migrate.c
  2006-04-29  0:36         ` Andrew Morton
  2006-04-29  0:46           ` Christoph Lameter
@ 2006-04-29  0:54           ` Christoph Lameter
  1 sibling, 0 replies; 25+ messages in thread
From: Christoph Lameter @ 2006-04-29  0:54 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mm, kamezawa.hiroyu, lee.schermerhorn, hugh

On Fri, 28 Apr 2006, Andrew Morton wrote:

> hm.  migrate_pages() locks two pages at the same time.  We've avoided doing
> that.
> 
> a) what prevents ab/ba deadlocks in the migration code?

Ahh. I forgot. Deadlocks are prevented because the page is freshly
allocated and only has a single reference that we are holding.

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/7] page migration: Reorder functions in migrate.c
  2006-04-29  0:46           ` Christoph Lameter
@ 2006-04-29  2:27             ` Andrew Morton
  2006-04-29  2:48               ` Christoph Lameter
  0 siblings, 1 reply; 25+ messages in thread
From: Andrew Morton @ 2006-04-29  2:27 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: linux-mm, kamezawa.hiroyu, lee.schermerhorn, hugh

Christoph Lameter <clameter@sgi.com> wrote:
>
> On Fri, 28 Apr 2006, Andrew Morton wrote:
> 
> > hm.  migrate_pages() locks two pages at the same time.  We've avoided doing
> > that.
> > 
> > a) what prevents ab/ba deadlocks in the migration code?
> 
> Nothing right now.
> 

OIC.

> 
> > b) if some other part of the kernel later decides to lock two pages at
> >    the same time, what protocol should that code follow to avoid ab/ba
> >    deadlocks?   lowest-pfn-first might be one.
> 
> We could just do a TestSetPageLocked() on the newpage. If it fails then we 
> postphone migration to the next loop. 
> 
> Patch on top of the one i just sent you or after the cleanup patches?
> 

On top of page-migration-fix-fallback-behavior-for-dirty-pages.patch,
please.  This is an unprivileged-user triggerable deadlock, no?

--
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:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 1/7] page migration: Reorder functions in migrate.c
  2006-04-29  2:27             ` Andrew Morton
@ 2006-04-29  2:48               ` Christoph Lameter
  0 siblings, 0 replies; 25+ messages in thread
From: Christoph Lameter @ 2006-04-29  2:48 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-mm, kamezawa.hiroyu, lee.schermerhorn, hugh

On Fri, 28 Apr 2006, Andrew Morton wrote:

> On top of page-migration-fix-fallback-behavior-for-dirty-pages.patch,
> please.  This is an unprivileged-user triggerable deadlock, no?

No change of a deadlock. Page is guaranteed to be only referenced by the 
page migration code at the start of migrating a page.

--
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:"dont@kvack.org"> email@kvack.org </a>

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

end of thread, other threads:[~2006-04-29  2:48 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-28  6:03 [PATCH 1/7] page migration: Reorder functions in migrate.c Christoph Lameter
2006-04-28  6:03 ` [PATCH 2/7] page migration: Remove unnecessarily exported functions Christoph Lameter
2006-04-28  6:03 ` [PATCH 3/7] page migration: Change handling of address spaces Christoph Lameter
2006-04-28  6:03 ` [PATCH 4/7] page migration: Drop nr_refs parameter Christoph Lameter
2006-04-28  7:30   ` KAMEZAWA Hiroyuki
2006-04-28 13:57     ` Christoph Lameter
2006-04-28  6:03 ` [PATCH 5/7] page migration: synchronize from and to lists Christoph Lameter
2006-04-28  7:46   ` KAMEZAWA Hiroyuki
2006-04-28 15:31     ` Christoph Lameter
2006-04-29  0:27       ` KAMEZAWA Hiroyuki
2006-04-29  0:33         ` Christoph Lameter
2006-04-29  0:44           ` KAMEZAWA Hiroyuki
2006-04-29  0:46             ` Christoph Lameter
2006-04-28  6:03 ` [PATCH 6/7] page migration: Extract try_to_unmap Christoph Lameter
2006-04-28  6:03 ` [PATCH 7/7] page migration: Add new fallback function Christoph Lameter
2006-04-28  6:42   ` Christoph Lameter
2006-04-28 22:08 ` [PATCH 1/7] page migration: Reorder functions in migrate.c Andrew Morton
2006-04-28 23:01   ` Christoph Lameter
2006-04-28 23:18     ` Andrew Morton
2006-04-29  0:14       ` Christoph Lameter
2006-04-29  0:36         ` Andrew Morton
2006-04-29  0:46           ` Christoph Lameter
2006-04-29  2:27             ` Andrew Morton
2006-04-29  2:48               ` Christoph Lameter
2006-04-29  0:54           ` Christoph Lameter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).