Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[firefly-linux-kernel-4.4.55.git] / mm / memcontrol.c
index 1a2020d72ca0071f9fc777c2c6289924838754c8..795e525afaba8914f3f8863de6a7299d84898ada 100644 (file)
@@ -405,6 +405,12 @@ enum charge_type {
 static void mem_cgroup_get(struct mem_cgroup *memcg);
 static void mem_cgroup_put(struct mem_cgroup *memcg);
 
+static inline
+struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *s)
+{
+       return container_of(s, struct mem_cgroup, css);
+}
+
 /* Writing them here to avoid exposing memcg's inner layout */
 #ifdef CONFIG_MEMCG_KMEM
 #include <net/sock.h>
@@ -862,9 +868,8 @@ static void memcg_check_events(struct mem_cgroup *memcg, struct page *page)
 
 struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)
 {
-       return container_of(cgroup_subsys_state(cont,
-                               mem_cgroup_subsys_id), struct mem_cgroup,
-                               css);
+       return mem_cgroup_from_css(
+               cgroup_subsys_state(cont, mem_cgroup_subsys_id));
 }
 
 struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
@@ -877,8 +882,7 @@ struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
        if (unlikely(!p))
                return NULL;
 
-       return container_of(task_subsys_state(p, mem_cgroup_subsys_id),
-                               struct mem_cgroup, css);
+       return mem_cgroup_from_css(task_subsys_state(p, mem_cgroup_subsys_id));
 }
 
 struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm)
@@ -964,8 +968,7 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
                css = css_get_next(&mem_cgroup_subsys, id + 1, &root->css, &id);
                if (css) {
                        if (css == &root->css || css_tryget(css))
-                               memcg = container_of(css,
-                                                    struct mem_cgroup, css);
+                               memcg = mem_cgroup_from_css(css);
                } else
                        id = 0;
                rcu_read_unlock();
@@ -2494,7 +2497,7 @@ static struct mem_cgroup *mem_cgroup_lookup(unsigned short id)
        css = css_lookup(&mem_cgroup_subsys, id);
        if (!css)
                return NULL;
-       return container_of(css, struct mem_cgroup, css);
+       return mem_cgroup_from_css(css);
 }
 
 struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
@@ -2818,14 +2821,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;
@@ -2848,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);
 }