Nuke duplicate header from sysctl.c
[cascardo/linux.git] / mm / migrate.c
index 857a987..a73504f 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/mempolicy.h>
 #include <linux/vmalloc.h>
 #include <linux/security.h>
+#include <linux/memcontrol.h>
 
 #include "internal.h"
 
@@ -152,6 +153,11 @@ static void remove_migration_pte(struct vm_area_struct *vma,
                return;
        }
 
+       if (mem_cgroup_charge(new, mm, GFP_KERNEL)) {
+               pte_unmap(ptep);
+               return;
+       }
+
        ptl = pte_lockptr(mm, pmd);
        spin_lock(ptl);
        pte = *ptep;
@@ -587,9 +593,10 @@ static int move_to_new_page(struct page *newpage, struct page *page)
        else
                rc = fallback_migrate_page(mapping, newpage, page);
 
-       if (!rc)
+       if (!rc) {
+               mem_cgroup_page_migration(page, newpage);
                remove_migration_ptes(page, newpage);
-       else
+       else
                newpage->mapping = NULL;
 
        unlock_page(newpage);
@@ -608,6 +615,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
        int *result = NULL;
        struct page *newpage = get_new_page(page, private, &result);
        int rcu_locked = 0;
+       int charge = 0;
 
        if (!newpage)
                return -ENOMEM;
@@ -667,14 +675,19 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
                goto rcu_unlock;
        }
 
+       charge = mem_cgroup_prepare_migration(page);
        /* Establish migration ptes or remove ptes */
        try_to_unmap(page, 1);
 
        if (!page_mapped(page))
                rc = move_to_new_page(newpage, page);
 
-       if (rc)
+       if (rc) {
                remove_migration_ptes(page, page);
+               if (charge)
+                       mem_cgroup_end_migration(page);
+       } else if (charge)
+               mem_cgroup_end_migration(newpage);
 rcu_unlock:
        if (rcu_locked)
                rcu_read_unlock();