diff options
Diffstat (limited to 'mm/migrate.c')
-rw-r--r-- | mm/migrate.c | 22 |
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); | ||
708 | rcu_unlock: | 714 | rcu_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 | ||
727 | move_newpage: | 733 | move_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. |