From fd3ae75ea4335f69b474547d524a57a1e961c341 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 4 Mar 2008 14:29:06 -0800 Subject: [PATCH] --- yaml --- r: 86817 b: refs/heads/master c: 98837c7f82ef78aa38f40462aa2fcac68fd3acbf h: refs/heads/master i: 86815: d278b32e8aa7d05a4d861330ad709e8c2df00dda v: v3 --- [refs] | 2 +- trunk/mm/migrate.c | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index c936c537a495..fc401cd30d3e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 61469f1d51777fc3b6d8d70da8373ee77ee13349 +refs/heads/master: 98837c7f82ef78aa38f40462aa2fcac68fd3acbf diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index a73504ff5ab9..4e0eccca5e26 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -153,11 +153,6 @@ 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; @@ -169,6 +164,20 @@ static void remove_migration_pte(struct vm_area_struct *vma, if (!is_migration_entry(entry) || migration_entry_to_page(entry) != old) goto out; + /* + * Yes, ignore the return value from a GFP_ATOMIC mem_cgroup_charge. + * Failure is not an option here: we're now expected to remove every + * migration pte, and will cause crashes otherwise. Normally this + * is not an issue: mem_cgroup_prepare_migration bumped up the old + * page_cgroup count for safety, that's now attached to the new page, + * so this charge should just be another incrementation of the count, + * to keep in balance with rmap.c's mem_cgroup_uncharging. But if + * there's been a force_empty, those reference counts may no longer + * be reliable, and this charge can actually fail: oh well, we don't + * make the situation any worse by proceeding as if it had succeeded. + */ + mem_cgroup_charge(new, mm, GFP_ATOMIC); + get_page(new); pte = pte_mkold(mk_pte(new, vma->vm_page_prot)); if (is_write_migration_entry(entry))