diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 94da8ee9e2c2..9c72d5d5372a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -381,16 +381,25 @@ static void mem_cgroup_put(struct mem_cgroup *memcg); | |||
381 | static bool mem_cgroup_is_root(struct mem_cgroup *memcg); | 381 | static bool mem_cgroup_is_root(struct mem_cgroup *memcg); |
382 | void sock_update_memcg(struct sock *sk) | 382 | void sock_update_memcg(struct sock *sk) |
383 | { | 383 | { |
384 | /* A socket spends its whole life in the same cgroup */ | ||
385 | if (sk->sk_cgrp) { | ||
386 | WARN_ON(1); | ||
387 | return; | ||
388 | } | ||
389 | if (static_branch(&memcg_socket_limit_enabled)) { | 384 | if (static_branch(&memcg_socket_limit_enabled)) { |
390 | struct mem_cgroup *memcg; | 385 | struct mem_cgroup *memcg; |
391 | 386 | ||
392 | BUG_ON(!sk->sk_prot->proto_cgroup); | 387 | BUG_ON(!sk->sk_prot->proto_cgroup); |
393 | 388 | ||
389 | /* Socket cloning can throw us here with sk_cgrp already | ||
390 | * filled. It won't however, necessarily happen from | ||
391 | * process context. So the test for root memcg given | ||
392 | * the current task's memcg won't help us in this case. | ||
393 | * | ||
394 | * Respecting the original socket's memcg is a better | ||
395 | * decision in this case. | ||
396 | */ | ||
397 | if (sk->sk_cgrp) { | ||
398 | BUG_ON(mem_cgroup_is_root(sk->sk_cgrp->memcg)); | ||
399 | mem_cgroup_get(sk->sk_cgrp->memcg); | ||
400 | return; | ||
401 | } | ||
402 | |||
394 | rcu_read_lock(); | 403 | rcu_read_lock(); |
395 | memcg = mem_cgroup_from_task(current); | 404 | memcg = mem_cgroup_from_task(current); |
396 | if (!mem_cgroup_is_root(memcg)) { | 405 | if (!mem_cgroup_is_root(memcg)) { |