aboutsummaryrefslogtreecommitdiffstats
path: root/mm/migrate.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/migrate.c')
-rw-r--r--mm/migrate.c54
1 files changed, 40 insertions, 14 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index 6a207e8d17ea..a73504ff5ab9 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -29,6 +29,7 @@
29#include <linux/mempolicy.h> 29#include <linux/mempolicy.h>
30#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
31#include <linux/security.h> 31#include <linux/security.h>
32#include <linux/memcontrol.h>
32 33
33#include "internal.h" 34#include "internal.h"
34 35
@@ -115,11 +116,6 @@ int putback_lru_pages(struct list_head *l)
115 return count; 116 return count;
116} 117}
117 118
118static inline int is_swap_pte(pte_t pte)
119{
120 return !pte_none(pte) && !pte_present(pte) && !pte_file(pte);
121}
122
123/* 119/*
124 * Restore a potential migration pte to a working pte entry 120 * Restore a potential migration pte to a working pte entry
125 */ 121 */
@@ -157,6 +153,11 @@ static void remove_migration_pte(struct vm_area_struct *vma,
157 return; 153 return;
158 } 154 }
159 155
156 if (mem_cgroup_charge(new, mm, GFP_KERNEL)) {
157 pte_unmap(ptep);
158 return;
159 }
160
160 ptl = pte_lockptr(mm, pmd); 161 ptl = pte_lockptr(mm, pmd);
161 spin_lock(ptl); 162 spin_lock(ptl);
162 pte = *ptep; 163 pte = *ptep;
@@ -592,9 +593,10 @@ static int move_to_new_page(struct page *newpage, struct page *page)
592 else 593 else
593 rc = fallback_migrate_page(mapping, newpage, page); 594 rc = fallback_migrate_page(mapping, newpage, page);
594 595
595 if (!rc) 596 if (!rc) {
597 mem_cgroup_page_migration(page, newpage);
596 remove_migration_ptes(page, newpage); 598 remove_migration_ptes(page, newpage);
597 else 599 } else
598 newpage->mapping = NULL; 600 newpage->mapping = NULL;
599 601
600 unlock_page(newpage); 602 unlock_page(newpage);
@@ -613,6 +615,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
613 int *result = NULL; 615 int *result = NULL;
614 struct page *newpage = get_new_page(page, private, &result); 616 struct page *newpage = get_new_page(page, private, &result);
615 int rcu_locked = 0; 617 int rcu_locked = 0;
618 int charge = 0;
616 619
617 if (!newpage) 620 if (!newpage)
618 return -ENOMEM; 621 return -ENOMEM;
@@ -645,23 +648,46 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
645 rcu_read_lock(); 648 rcu_read_lock();
646 rcu_locked = 1; 649 rcu_locked = 1;
647 } 650 }
651
648 /* 652 /*
649 * This is a corner case handling. 653 * Corner case handling:
650 * When a new swap-cache is read into, it is linked to LRU 654 * 1. When a new swap-cache page is read into, it is added to the LRU
651 * and treated as swapcache but has no rmap yet. 655 * and treated as swapcache but it has no rmap yet.
652 * Calling try_to_unmap() against a page->mapping==NULL page is 656 * Calling try_to_unmap() against a page->mapping==NULL page will
653 * BUG. So handle it here. 657 * trigger a BUG. So handle it here.
658 * 2. An orphaned page (see truncate_complete_page) might have
659 * fs-private metadata. The page can be picked up due to memory
660 * offlining. Everywhere else except page reclaim, the page is
661 * invisible to the vm, so the page can not be migrated. So try to
662 * free the metadata, so the page can be freed.
654 */ 663 */
655 if (!page->mapping) 664 if (!page->mapping) {
665 if (!PageAnon(page) && PagePrivate(page)) {
666 /*
667 * Go direct to try_to_free_buffers() here because
668 * a) that's what try_to_release_page() would do anyway
669 * b) we may be under rcu_read_lock() here, so we can't
670 * use GFP_KERNEL which is what try_to_release_page()
671 * needs to be effective.
672 */
673 try_to_free_buffers(page);
674 }
656 goto rcu_unlock; 675 goto rcu_unlock;
676 }
677
678 charge = mem_cgroup_prepare_migration(page);
657 /* Establish migration ptes or remove ptes */ 679 /* Establish migration ptes or remove ptes */
658 try_to_unmap(page, 1); 680 try_to_unmap(page, 1);
659 681
660 if (!page_mapped(page)) 682 if (!page_mapped(page))
661 rc = move_to_new_page(newpage, page); 683 rc = move_to_new_page(newpage, page);
662 684
663 if (rc) 685 if (rc) {
664 remove_migration_ptes(page, page); 686 remove_migration_ptes(page, page);
687 if (charge)
688 mem_cgroup_end_migration(page);
689 } else if (charge)
690 mem_cgroup_end_migration(newpage);
665rcu_unlock: 691rcu_unlock:
666 if (rcu_locked) 692 if (rcu_locked)
667 rcu_read_unlock(); 693 rcu_read_unlock();