Merge git://www.linux-watchdog.org/linux-watchdog
[deliverable/linux.git] / mm / memcontrol.c
index 94da8ee9e2c2a4b88eb3f58ae341f16435da701e..d87aa3510c5e0a0e62e6c97ec6f0a85420c40d9d 100644 (file)
@@ -381,16 +381,25 @@ static void mem_cgroup_put(struct mem_cgroup *memcg);
 static bool mem_cgroup_is_root(struct mem_cgroup *memcg);
 void sock_update_memcg(struct sock *sk)
 {
-       /* A socket spends its whole life in the same cgroup */
-       if (sk->sk_cgrp) {
-               WARN_ON(1);
-               return;
-       }
        if (static_branch(&memcg_socket_limit_enabled)) {
                struct mem_cgroup *memcg;
 
                BUG_ON(!sk->sk_prot->proto_cgroup);
 
+               /* Socket cloning can throw us here with sk_cgrp already
+                * filled. It won't however, necessarily happen from
+                * process context. So the test for root memcg given
+                * the current task's memcg won't help us in this case.
+                *
+                * Respecting the original socket's memcg is a better
+                * decision in this case.
+                */
+               if (sk->sk_cgrp) {
+                       BUG_ON(mem_cgroup_is_root(sk->sk_cgrp->memcg));
+                       mem_cgroup_get(sk->sk_cgrp->memcg);
+                       return;
+               }
+
                rcu_read_lock();
                memcg = mem_cgroup_from_task(current);
                if (!mem_cgroup_is_root(memcg)) {
@@ -5391,8 +5400,9 @@ static void mem_cgroup_clear_mc(void)
 
 static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
                                struct cgroup *cgroup,
-                               struct task_struct *p)
+                               struct cgroup_taskset *tset)
 {
+       struct task_struct *p = cgroup_taskset_first(tset);
        int ret = 0;
        struct mem_cgroup *memcg = mem_cgroup_from_cont(cgroup);
 
@@ -5430,7 +5440,7 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
 
 static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss,
                                struct cgroup *cgroup,
-                               struct task_struct *p)
+                               struct cgroup_taskset *tset)
 {
        mem_cgroup_clear_mc();
 }
@@ -5547,9 +5557,9 @@ retry:
 
 static void mem_cgroup_move_task(struct cgroup_subsys *ss,
                                struct cgroup *cont,
-                               struct cgroup *old_cont,
-                               struct task_struct *p)
+                               struct cgroup_taskset *tset)
 {
+       struct task_struct *p = cgroup_taskset_first(tset);
        struct mm_struct *mm = get_task_mm(p);
 
        if (mm) {
@@ -5564,19 +5574,18 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss,
 #else  /* !CONFIG_MMU */
 static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
                                struct cgroup *cgroup,
-                               struct task_struct *p)
+                               struct cgroup_taskset *tset)
 {
        return 0;
 }
 static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss,
                                struct cgroup *cgroup,
-                               struct task_struct *p)
+                               struct cgroup_taskset *tset)
 {
 }
 static void mem_cgroup_move_task(struct cgroup_subsys *ss,
                                struct cgroup *cont,
-                               struct cgroup *old_cont,
-                               struct task_struct *p)
+                               struct cgroup_taskset *tset)
 {
 }
 #endif
This page took 0.027934 seconds and 5 git commands to generate.