]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
mm: memcg: only check anon swapin page charges for swap cache
authorJohannes Weiner <hannes@cmpxchg.org>
Sat, 21 Jul 2012 00:54:33 +0000 (10:54 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 25 Jul 2012 03:53:07 +0000 (13:53 +1000)
shmem knows for sure that the page is in swap cache when attempting to
charge a page, because the cache charge entry function has a check for it.
Only anon pages may be removed from swap cache already when trying to
charge their swapin.

Adjust the comment, though: '4969c11 mm: fix swapin race condition' added
a stable PageSwapCache check under the page lock in the do_swap_page()
before calling the memory controller, so it's unuse_pte()'s pte_same()
that may fail.

Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Michal Hocko <mhocko@suse.cz>
Cc: David Rientjes <rientjes@google.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Wanpeng Li <liwp.linux@gmail.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/memcontrol.c

index 196d32e7a4aaaaf224b301870c582aa4eff2bcf1..2ac431620051f2f97fb8600219d254362fa39402 100644 (file)
@@ -2819,14 +2819,6 @@ static int __mem_cgroup_try_charge_swapin(struct mm_struct *mm,
                return 0;
        if (!do_swap_account)
                goto charge_cur_mm;
-       /*
-        * A racing thread's fault, or swapoff, may have already updated
-        * the pte, and even removed page from swap cache: in those cases
-        * do_swap_page()'s pte_same() test will fail; but there's also a
-        * KSM case which does need to charge the page.
-        */
-       if (!PageSwapCache(page))
-               goto charge_cur_mm;
        memcg = try_get_mem_cgroup_from_page(page);
        if (!memcg)
                goto charge_cur_mm;
@@ -2851,6 +2843,20 @@ int mem_cgroup_try_charge_swapin(struct mm_struct *mm, struct page *page,
        *memcgp = NULL;
        if (mem_cgroup_disabled())
                return 0;
+       /*
+        * A racing thread's fault, or swapoff, may have already
+        * updated the pte, and even removed page from swap cache: in
+        * those cases unuse_pte()'s pte_same() test will fail; but
+        * there's also a KSM case which does need to charge the page.
+        */
+       if (!PageSwapCache(page)) {
+               int ret;
+
+               ret = __mem_cgroup_try_charge(mm, gfp_mask, 1, memcgp, true);
+               if (ret == -EINTR)
+                       ret = 0;
+               return ret;
+       }
        return __mem_cgroup_try_charge_swapin(mm, page, gfp_mask, memcgp);
 }