aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMinchan Kim <minchan.kim@gmail.com>2011-10-31 20:06:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-31 20:30:45 -0400
commit0dabec93de633a87adfbbe1d800a4c56cd19d73b (patch)
tree51850bc562f8f95d284dbd7baeecfaefd573fccf
parentf80c0673610e36ae29d63e3297175e22f70dde5f (diff)
mm: migration: clean up unmap_and_move()
unmap_and_move() is one a big messy function. Clean it up. Signed-off-by: Minchan Kim <minchan.kim@gmail.com> Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Rik van Riel <riel@redhat.com> Cc: Michal Hocko <mhocko@suse.cz> Cc: Andrea Arcangeli <aarcange@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/migrate.c75
1 files changed, 40 insertions, 35 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index 14d0a6a632f6..33358f878111 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -621,38 +621,18 @@ static int move_to_new_page(struct page *newpage, struct page *page,
621 return rc; 621 return rc;
622} 622}
623 623
624/* 624static int __unmap_and_move(struct page *page, struct page *newpage,
625 * Obtain the lock on page, remove all ptes and migrate the page 625 int force, bool offlining, bool sync)
626 * to the newly allocated page in newpage.
627 */
628static int unmap_and_move(new_page_t get_new_page, unsigned long private,
629 struct page *page, int force, bool offlining, bool sync)
630{ 626{
631 int rc = 0; 627 int rc = -EAGAIN;
632 int *result = NULL;
633 struct page *newpage = get_new_page(page, private, &result);
634 int remap_swapcache = 1; 628 int remap_swapcache = 1;
635 int charge = 0; 629 int charge = 0;
636 struct mem_cgroup *mem; 630 struct mem_cgroup *mem;
637 struct anon_vma *anon_vma = NULL; 631 struct anon_vma *anon_vma = NULL;
638 632
639 if (!newpage)
640 return -ENOMEM;
641
642 if (page_count(page) == 1) {
643 /* page was freed from under us. So we are done. */
644 goto move_newpage;
645 }
646 if (unlikely(PageTransHuge(page)))
647 if (unlikely(split_huge_page(page)))
648 goto move_newpage;
649
650 /* prepare cgroup just returns 0 or -ENOMEM */
651 rc = -EAGAIN;
652
653 if (!trylock_page(page)) { 633 if (!trylock_page(page)) {
654 if (!force || !sync) 634 if (!force || !sync)
655 goto move_newpage; 635 goto out;
656 636
657 /* 637 /*
658 * It's not safe for direct compaction to call lock_page. 638 * It's not safe for direct compaction to call lock_page.
@@ -668,7 +648,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
668 * altogether. 648 * altogether.
669 */ 649 */
670 if (current->flags & PF_MEMALLOC) 650 if (current->flags & PF_MEMALLOC)
671 goto move_newpage; 651 goto out;
672 652
673 lock_page(page); 653 lock_page(page);
674 } 654 }
@@ -785,27 +765,52 @@ uncharge:
785 mem_cgroup_end_migration(mem, page, newpage, rc == 0); 765 mem_cgroup_end_migration(mem, page, newpage, rc == 0);
786unlock: 766unlock:
787 unlock_page(page); 767 unlock_page(page);
768out:
769 return rc;
770}
788 771
789move_newpage: 772/*
773 * Obtain the lock on page, remove all ptes and migrate the page
774 * to the newly allocated page in newpage.
775 */
776static int unmap_and_move(new_page_t get_new_page, unsigned long private,
777 struct page *page, int force, bool offlining, bool sync)
778{
779 int rc = 0;
780 int *result = NULL;
781 struct page *newpage = get_new_page(page, private, &result);
782
783 if (!newpage)
784 return -ENOMEM;
785
786 if (page_count(page) == 1) {
787 /* page was freed from under us. So we are done. */
788 goto out;
789 }
790
791 if (unlikely(PageTransHuge(page)))
792 if (unlikely(split_huge_page(page)))
793 goto out;
794
795 rc = __unmap_and_move(page, newpage, force, offlining, sync);
796out:
790 if (rc != -EAGAIN) { 797 if (rc != -EAGAIN) {
791 /* 798 /*
792 * A page that has been migrated has all references 799 * A page that has been migrated has all references
793 * removed and will be freed. A page that has not been 800 * removed and will be freed. A page that has not been
794 * migrated will have kepts its references and be 801 * migrated will have kepts its references and be
795 * restored. 802 * restored.
796 */ 803 */
797 list_del(&page->lru); 804 list_del(&page->lru);
798 dec_zone_page_state(page, NR_ISOLATED_ANON + 805 dec_zone_page_state(page, NR_ISOLATED_ANON +
799 page_is_file_cache(page)); 806 page_is_file_cache(page));
800 putback_lru_page(page); 807 putback_lru_page(page);
801 } 808 }
802
803 /* 809 /*
804 * Move the new page to the LRU. If migration was not successful 810 * Move the new page to the LRU. If migration was not successful
805 * then this will free the page. 811 * then this will free the page.
806 */ 812 */
807 putback_lru_page(newpage); 813 putback_lru_page(newpage);
808
809 if (result) { 814 if (result) {
810 if (rc) 815 if (rc)
811 *result = rc; 816 *result = rc;