aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2007-08-31 02:56:21 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-31 04:42:22 -0400
commit989f89c57e6361e7d16fbd9572b5da7d313b073d (patch)
treecd5f655709e1515568c1e1f309f169723ce3b084 /mm
parentd1254b12c93e1e586137a2ffef71fd33cf273f35 (diff)
fix rcu_read_lock() in page migraton
In migration fallback path, write_page() or lock_page() will be called. This causes sleep with holding rcu_read_lock(). For avoding that, just do rcu_lock if the page is Anon.(this is enough.) Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Acked-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/migrate.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index 37c73b902008..e2fdbce1874b 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -611,6 +611,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
611 int rc = 0; 611 int rc = 0;
612 int *result = NULL; 612 int *result = NULL;
613 struct page *newpage = get_new_page(page, private, &result); 613 struct page *newpage = get_new_page(page, private, &result);
614 int rcu_locked = 0;
614 615
615 if (!newpage) 616 if (!newpage)
616 return -ENOMEM; 617 return -ENOMEM;
@@ -636,8 +637,13 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
636 * we cannot notice that anon_vma is freed while we migrates a page. 637 * we cannot notice that anon_vma is freed while we migrates a page.
637 * This rcu_read_lock() delays freeing anon_vma pointer until the end 638 * This rcu_read_lock() delays freeing anon_vma pointer until the end
638 * of migration. File cache pages are no problem because of page_lock() 639 * of migration. File cache pages are no problem because of page_lock()
640 * File Caches may use write_page() or lock_page() in migration, then,
641 * just care Anon page here.
639 */ 642 */
640 rcu_read_lock(); 643 if (PageAnon(page)) {
644 rcu_read_lock();
645 rcu_locked = 1;
646 }
641 /* 647 /*
642 * This is a corner case handling. 648 * This is a corner case handling.
643 * When a new swap-cache is read into, it is linked to LRU 649 * When a new swap-cache is read into, it is linked to LRU
@@ -656,7 +662,8 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
656 if (rc) 662 if (rc)
657 remove_migration_ptes(page, page); 663 remove_migration_ptes(page, page);
658rcu_unlock: 664rcu_unlock:
659 rcu_read_unlock(); 665 if (rcu_locked)
666 rcu_read_unlock();
660 667
661unlock: 668unlock:
662 669