mm: memcontrol: consolidate cgroup socket tracking
authorJohannes Weiner <hannes@cmpxchg.org>
Sat, 8 Oct 2016 00:00:58 +0000 (17:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 8 Oct 2016 01:46:29 +0000 (18:46 -0700)
The cgroup core and the memory controller need to track socket ownership
for different purposes, but the tracking sites being entirely different
is kind of ugly.

Be a better citizen and rename the memory controller callbacks to match
the cgroup core callbacks, then move them to the same place.

[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/20160914194846.11153-3-hannes@cmpxchg.org
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Vladimir Davydov <vdavydov@virtuozzo.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/memcontrol.h
mm/memcontrol.c
net/core/sock.c
net/ipv4/tcp.c
net/ipv4/tcp_ipv4.c

index 0710143723bce194e7b77d80ef4314adb5e9e1d6..61d20c17f3b7e40ba706a49da463c2f9eabd7d93 100644 (file)
@@ -773,13 +773,13 @@ static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb,
 #endif /* CONFIG_CGROUP_WRITEBACK */
 
 struct sock;
-void sock_update_memcg(struct sock *sk);
-void sock_release_memcg(struct sock *sk);
 bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages);
 void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages);
 #ifdef CONFIG_MEMCG
 extern struct static_key_false memcg_sockets_enabled_key;
 #define mem_cgroup_sockets_enabled static_branch_unlikely(&memcg_sockets_enabled_key)
+void mem_cgroup_sk_alloc(struct sock *sk);
+void mem_cgroup_sk_free(struct sock *sk);
 static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg)
 {
        if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && memcg->tcpmem_pressure)
@@ -792,6 +792,8 @@ static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg)
 }
 #else
 #define mem_cgroup_sockets_enabled 0
+static inline void mem_cgroup_sk_alloc(struct sock *sk) { };
+static inline void mem_cgroup_sk_free(struct sock *sk) { };
 static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg)
 {
        return false;
index 60bb830abc345bee90d2a15a0c9d532baaec5aea..ae052b5e3315217874569d0c1cf57ade9cea99a1 100644 (file)
@@ -2939,16 +2939,16 @@ static int memcg_update_tcp_limit(struct mem_cgroup *memcg, unsigned long limit)
                /*
                 * The active flag needs to be written after the static_key
                 * update. This is what guarantees that the socket activation
-                * function is the last one to run. See sock_update_memcg() for
-                * details, and note that we don't mark any socket as belonging
-                * to this memcg until that flag is up.
+                * function is the last one to run. See mem_cgroup_sk_alloc()
+                * for details, and note that we don't mark any socket as
+                * belonging to this memcg until that flag is up.
                 *
                 * We need to do this, because static_keys will span multiple
                 * sites, but we can't control their order. If we mark a socket
                 * as accounted, but the accounting functions are not patched in
                 * yet, we'll lose accounting.
                 *
-                * We never race with the readers in sock_update_memcg(),
+                * We never race with the readers in mem_cgroup_sk_alloc(),
                 * because when this value change, the code to process it is not
                 * patched in yet.
                 */
@@ -5651,11 +5651,15 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage)
 DEFINE_STATIC_KEY_FALSE(memcg_sockets_enabled_key);
 EXPORT_SYMBOL(memcg_sockets_enabled_key);
 
-void sock_update_memcg(struct sock *sk)
+void mem_cgroup_sk_alloc(struct sock *sk)
 {
        struct mem_cgroup *memcg;
 
-       /* Socket cloning can throw us here with sk_cgrp already
+       if (!mem_cgroup_sockets_enabled)
+               return;
+
+       /*
+        * Socket cloning can throw us here with sk_memcg 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.
@@ -5680,12 +5684,11 @@ void sock_update_memcg(struct sock *sk)
 out:
        rcu_read_unlock();
 }
-EXPORT_SYMBOL(sock_update_memcg);
 
-void sock_release_memcg(struct sock *sk)
+void mem_cgroup_sk_free(struct sock *sk)
 {
-       WARN_ON(!sk->sk_memcg);
-       css_put(&sk->sk_memcg->css);
+       if (sk->sk_memcg)
+               css_put(&sk->sk_memcg->css);
 }
 
 /**
index 038e660ef84471c7a3322b2661f6af4ff662e715..c73e28fc9c2a45225af39f7905072456d4380c7f 100644 (file)
@@ -1363,6 +1363,7 @@ static void sk_prot_free(struct proto *prot, struct sock *sk)
        slab = prot->slab;
 
        cgroup_sk_free(&sk->sk_cgrp_data);
+       mem_cgroup_sk_free(sk);
        security_sk_free(sk);
        if (slab != NULL)
                kmem_cache_free(slab, sk);
@@ -1399,6 +1400,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
                sock_net_set(sk, net);
                atomic_set(&sk->sk_wmem_alloc, 1);
 
+               mem_cgroup_sk_alloc(sk);
                cgroup_sk_alloc(&sk->sk_cgrp_data);
                sock_update_classid(&sk->sk_cgrp_data);
                sock_update_netprioidx(&sk->sk_cgrp_data);
@@ -1545,6 +1547,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
                newsk->sk_incoming_cpu = raw_smp_processor_id();
                atomic64_set(&newsk->sk_cookie, 0);
 
+               mem_cgroup_sk_alloc(newsk);
                cgroup_sk_alloc(&newsk->sk_cgrp_data);
 
                /*
@@ -1569,9 +1572,6 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
                sk_set_socket(newsk, NULL);
                newsk->sk_wq = NULL;
 
-               if (mem_cgroup_sockets_enabled && sk->sk_memcg)
-                       sock_update_memcg(newsk);
-
                if (newsk->sk_prot->sockets_allocated)
                        sk_sockets_allocated_inc(newsk);
 
index f253e5019d227461551b2dd3ba384e85a5e2a287..ab984d2ff88aee5c3ce269d765681b39be2e7837 100644 (file)
@@ -424,8 +424,6 @@ void tcp_init_sock(struct sock *sk)
        sk->sk_rcvbuf = sysctl_tcp_rmem[1];
 
        local_bh_disable();
-       if (mem_cgroup_sockets_enabled)
-               sock_update_memcg(sk);
        sk_sockets_allocated_inc(sk);
        local_bh_enable();
 }
index 7ac37c314312b71e8db7e771b5191ab20785e899..bd5e8d10893fb6abffa6b0aa65de239b0000fe5b 100644 (file)
@@ -1871,9 +1871,6 @@ void tcp_v4_destroy_sock(struct sock *sk)
        local_bh_disable();
        sk_sockets_allocated_dec(sk);
        local_bh_enable();
-
-       if (mem_cgroup_sockets_enabled && sk->sk_memcg)
-               sock_release_memcg(sk);
 }
 EXPORT_SYMBOL(tcp_v4_destroy_sock);