mm: memcg: lockdep annotation for memcg OOM lock
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / memcontrol.c
index 34d3ca9..7e11cb7 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/page_cgroup.h>
 #include <linux/cpu.h>
 #include <linux/oom.h>
+#include <linux/lockdep.h>
 #include "internal.h"
 #include <net/sock.h>
 #include <net/ip.h>
@@ -2046,6 +2047,12 @@ static int mem_cgroup_soft_reclaim(struct mem_cgroup *root_memcg,
        return total;
 }
 
+#ifdef CONFIG_LOCKDEP
+static struct lockdep_map memcg_oom_lock_dep_map = {
+       .name = "memcg_oom_lock",
+};
+#endif
+
 static DEFINE_SPINLOCK(memcg_oom_lock);
 
 /*
@@ -2083,7 +2090,8 @@ static bool mem_cgroup_oom_trylock(struct mem_cgroup *memcg)
                        }
                        iter->oom_lock = false;
                }
-       }
+       } else
+               mutex_acquire(&memcg_oom_lock_dep_map, 0, 1, _RET_IP_);
 
        spin_unlock(&memcg_oom_lock);
 
@@ -2095,6 +2103,7 @@ static void mem_cgroup_oom_unlock(struct mem_cgroup *memcg)
        struct mem_cgroup *iter;
 
        spin_lock(&memcg_oom_lock);
+       mutex_release(&memcg_oom_lock_dep_map, 1, _RET_IP_);
        for_each_mem_cgroup_tree(iter, memcg)
                iter->oom_lock = false;
        spin_unlock(&memcg_oom_lock);
@@ -2765,10 +2774,10 @@ done:
        *ptr = memcg;
        return 0;
 nomem:
-       *ptr = NULL;
-       if (gfp_mask & __GFP_NOFAIL)
-               return 0;
-       return -ENOMEM;
+       if (!(gfp_mask & __GFP_NOFAIL)) {
+               *ptr = NULL;
+               return -ENOMEM;
+       }
 bypass:
        *ptr = root_mem_cgroup;
        return -EINTR;
@@ -3774,7 +3783,7 @@ void mem_cgroup_move_account_page_stat(struct mem_cgroup *from,
        /* Update stat data for mem_cgroup */
        preempt_disable();
        WARN_ON_ONCE(from->stat->count[idx] < nr_pages);
-       __this_cpu_add(from->stat->count[idx], -nr_pages);
+       __this_cpu_sub(from->stat->count[idx], nr_pages);
        __this_cpu_add(to->stat->count[idx], nr_pages);
        preempt_enable();
 }