From: Christoph Lameter <clameter@sgi.com>
To: akpm@osdl.org
Cc: linux-mm@kvack.org,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
Lee Schermerhorn <lee.schermerhorn@hp.com>,
Christoph Lameter <clameter@sgi.com>,
Hugh Dickins <hugh@veritas.com>
Subject: [PATCH 3/7] page migration: Change handling of address spaces
Date: Thu, 27 Apr 2006 23:03:12 -0700 (PDT) [thread overview]
Message-ID: <20060428060312.30257.16842.sendpatchset@schroedinger.engr.sgi.com> (raw)
In-Reply-To: <20060428060302.30257.76871.sendpatchset@schroedinger.engr.sgi.com>
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>
next prev parent reply other threads:[~2006-04-28 6:03 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060428060312.30257.16842.sendpatchset@schroedinger.engr.sgi.com \
--to=clameter@sgi.com \
--cc=akpm@osdl.org \
--cc=hugh@veritas.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=lee.schermerhorn@hp.com \
--cc=linux-mm@kvack.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox