aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/migrate.c48
1 files changed, 19 insertions, 29 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index 89a6bc8cd307..a20cf12edede 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -622,7 +622,6 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
622 int *result = NULL; 622 int *result = NULL;
623 struct page *newpage = get_new_page(page, private, &result); 623 struct page *newpage = get_new_page(page, private, &result);
624 int remap_swapcache = 1; 624 int remap_swapcache = 1;
625 int rcu_locked = 0;
626 int charge = 0; 625 int charge = 0;
627 struct mem_cgroup *mem = NULL; 626 struct mem_cgroup *mem = NULL;
628 struct anon_vma *anon_vma = NULL; 627 struct anon_vma *anon_vma = NULL;
@@ -694,20 +693,26 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
694 /* 693 /*
695 * By try_to_unmap(), page->mapcount goes down to 0 here. In this case, 694 * By try_to_unmap(), page->mapcount goes down to 0 here. In this case,
696 * we cannot notice that anon_vma is freed while we migrates a page. 695 * we cannot notice that anon_vma is freed while we migrates a page.
697 * This rcu_read_lock() delays freeing anon_vma pointer until the end 696 * This get_anon_vma() delays freeing anon_vma pointer until the end
698 * of migration. File cache pages are no problem because of page_lock() 697 * of migration. File cache pages are no problem because of page_lock()
699 * File Caches may use write_page() or lock_page() in migration, then, 698 * File Caches may use write_page() or lock_page() in migration, then,
700 * just care Anon page here. 699 * just care Anon page here.
701 */ 700 */
702 if (PageAnon(page)) { 701 if (PageAnon(page)) {
703 rcu_read_lock(); 702 /*
704 rcu_locked = 1; 703 * Only page_lock_anon_vma() understands the subtleties of
705 704 * getting a hold on an anon_vma from outside one of its mms.
706 /* Determine how to safely use anon_vma */ 705 */
707 if (!page_mapped(page)) { 706 anon_vma = page_lock_anon_vma(page);
708 if (!PageSwapCache(page)) 707 if (anon_vma) {
709 goto rcu_unlock; 708 /*
710 709 * Take a reference count on the anon_vma if the
710 * page is mapped so that it is guaranteed to
711 * exist when the page is remapped later
712 */
713 get_anon_vma(anon_vma);
714 page_unlock_anon_vma(anon_vma);
715 } else if (PageSwapCache(page)) {
711 /* 716 /*
712 * We cannot be sure that the anon_vma of an unmapped 717 * We cannot be sure that the anon_vma of an unmapped
713 * swapcache page is safe to use because we don't 718 * swapcache page is safe to use because we don't
@@ -722,13 +727,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
722 */ 727 */
723 remap_swapcache = 0; 728 remap_swapcache = 0;
724 } else { 729 } else {
725 /* 730 goto uncharge;
726 * Take a reference count on the anon_vma if the
727 * page is mapped so that it is guaranteed to
728 * exist when the page is remapped later
729 */
730 anon_vma = page_anon_vma(page);
731 get_anon_vma(anon_vma);
732 } 731 }
733 } 732 }
734 733
@@ -745,16 +744,10 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
745 * free the metadata, so the page can be freed. 744 * free the metadata, so the page can be freed.
746 */ 745 */
747 if (!page->mapping) { 746 if (!page->mapping) {
748 if (!PageAnon(page) && page_has_private(page)) { 747 VM_BUG_ON(PageAnon(page));
749 /* 748 if (page_has_private(page)) {
750 * Go direct to try_to_free_buffers() here because
751 * a) that's what try_to_release_page() would do anyway
752 * b) we may be under rcu_read_lock() here, so we can't
753 * use GFP_KERNEL which is what try_to_release_page()
754 * needs to be effective.
755 */
756 try_to_free_buffers(page); 749 try_to_free_buffers(page);
757 goto rcu_unlock; 750 goto uncharge;
758 } 751 }
759 goto skip_unmap; 752 goto skip_unmap;
760 } 753 }
@@ -768,14 +761,11 @@ skip_unmap:
768 761
769 if (rc && remap_swapcache) 762 if (rc && remap_swapcache)
770 remove_migration_ptes(page, page); 763 remove_migration_ptes(page, page);
771rcu_unlock:
772 764
773 /* Drop an anon_vma reference if we took one */ 765 /* Drop an anon_vma reference if we took one */
774 if (anon_vma) 766 if (anon_vma)
775 drop_anon_vma(anon_vma); 767 drop_anon_vma(anon_vma);
776 768
777 if (rcu_locked)
778 rcu_read_unlock();
779uncharge: 769uncharge:
780 if (!charge) 770 if (!charge)
781 mem_cgroup_end_migration(mem, page, newpage); 771 mem_cgroup_end_migration(mem, page, newpage);