aboutsummaryrefslogtreecommitdiffstats
path: root/mm/migrate.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/migrate.c')
-rw-r--r--mm/migrate.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index 376cceba82f9..f6d7f8efd1a8 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -358,6 +358,10 @@ static int migrate_page_move_mapping(struct address_space *mapping,
358 __inc_zone_page_state(newpage, NR_FILE_PAGES); 358 __inc_zone_page_state(newpage, NR_FILE_PAGES);
359 359
360 write_unlock_irq(&mapping->tree_lock); 360 write_unlock_irq(&mapping->tree_lock);
361 if (!PageSwapCache(newpage)) {
362 mem_cgroup_uncharge_page(page);
363 mem_cgroup_getref(newpage);
364 }
361 365
362 return 0; 366 return 0;
363} 367}
@@ -611,7 +615,6 @@ static int move_to_new_page(struct page *newpage, struct page *page)
611 rc = fallback_migrate_page(mapping, newpage, page); 615 rc = fallback_migrate_page(mapping, newpage, page);
612 616
613 if (!rc) { 617 if (!rc) {
614 mem_cgroup_page_migration(page, newpage);
615 remove_migration_ptes(page, newpage); 618 remove_migration_ptes(page, newpage);
616 } else 619 } else
617 newpage->mapping = NULL; 620 newpage->mapping = NULL;
@@ -641,6 +644,14 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
641 /* page was freed from under us. So we are done. */ 644 /* page was freed from under us. So we are done. */
642 goto move_newpage; 645 goto move_newpage;
643 646
647 charge = mem_cgroup_prepare_migration(page, newpage);
648 if (charge == -ENOMEM) {
649 rc = -ENOMEM;
650 goto move_newpage;
651 }
652 /* prepare cgroup just returns 0 or -ENOMEM */
653 BUG_ON(charge);
654
644 rc = -EAGAIN; 655 rc = -EAGAIN;
645 if (TestSetPageLocked(page)) { 656 if (TestSetPageLocked(page)) {
646 if (!force) 657 if (!force)
@@ -692,19 +703,14 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
692 goto rcu_unlock; 703 goto rcu_unlock;
693 } 704 }
694 705
695 charge = mem_cgroup_prepare_migration(page);
696 /* Establish migration ptes or remove ptes */ 706 /* Establish migration ptes or remove ptes */
697 try_to_unmap(page, 1); 707 try_to_unmap(page, 1);
698 708
699 if (!page_mapped(page)) 709 if (!page_mapped(page))
700 rc = move_to_new_page(newpage, page); 710 rc = move_to_new_page(newpage, page);
701 711
702 if (rc) { 712 if (rc)
703 remove_migration_ptes(page, page); 713 remove_migration_ptes(page, page);
704 if (charge)
705 mem_cgroup_end_migration(page);
706 } else if (charge)
707 mem_cgroup_end_migration(newpage);
708rcu_unlock: 714rcu_unlock:
709 if (rcu_locked) 715 if (rcu_locked)
710 rcu_read_unlock(); 716 rcu_read_unlock();
@@ -725,6 +731,8 @@ unlock:
725 } 731 }
726 732
727move_newpage: 733move_newpage:
734 if (!charge)
735 mem_cgroup_end_migration(newpage);
728 /* 736 /*
729 * Move the new page to the LRU. If migration was not successful 737 * Move the new page to the LRU. If migration was not successful
730 * then this will free the page. 738 * then this will free the page.