|
@@ -593,9 +593,10 @@ static int move_to_new_page(struct page *newpage, struct page *page)
|
|
else
|
|
else
|
|
rc = fallback_migrate_page(mapping, newpage, page);
|
|
rc = fallback_migrate_page(mapping, newpage, page);
|
|
|
|
|
|
- if (!rc)
|
|
|
|
|
|
+ if (!rc) {
|
|
|
|
+ mem_cgroup_page_migration(page, newpage);
|
|
remove_migration_ptes(page, newpage);
|
|
remove_migration_ptes(page, newpage);
|
|
- else
|
|
|
|
|
|
+ } else
|
|
newpage->mapping = NULL;
|
|
newpage->mapping = NULL;
|
|
|
|
|
|
unlock_page(newpage);
|
|
unlock_page(newpage);
|
|
@@ -614,6 +615,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
|
|
int *result = NULL;
|
|
int *result = NULL;
|
|
struct page *newpage = get_new_page(page, private, &result);
|
|
struct page *newpage = get_new_page(page, private, &result);
|
|
int rcu_locked = 0;
|
|
int rcu_locked = 0;
|
|
|
|
+ int charge = 0;
|
|
|
|
|
|
if (!newpage)
|
|
if (!newpage)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
@@ -673,14 +675,19 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
|
|
goto rcu_unlock;
|
|
goto rcu_unlock;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ charge = mem_cgroup_prepare_migration(page);
|
|
/* Establish migration ptes or remove ptes */
|
|
/* Establish migration ptes or remove ptes */
|
|
try_to_unmap(page, 1);
|
|
try_to_unmap(page, 1);
|
|
|
|
|
|
if (!page_mapped(page))
|
|
if (!page_mapped(page))
|
|
rc = move_to_new_page(newpage, page);
|
|
rc = move_to_new_page(newpage, page);
|
|
|
|
|
|
- if (rc)
|
|
|
|
|
|
+ if (rc) {
|
|
remove_migration_ptes(page, page);
|
|
remove_migration_ptes(page, page);
|
|
|
|
+ if (charge)
|
|
|
|
+ mem_cgroup_end_migration(page);
|
|
|
|
+ } else if (charge)
|
|
|
|
+ mem_cgroup_end_migration(newpage);
|
|
rcu_unlock:
|
|
rcu_unlock:
|
|
if (rcu_locked)
|
|
if (rcu_locked)
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|