summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/memcontrol.h9
-rw-r--r--mm/memcontrol.c56
-rw-r--r--net/core/sock.c9
-rw-r--r--net/ipv4/tcp.c3
-rw-r--r--net/ipv4/tcp_ipv4.c4
5 files changed, 32 insertions, 49 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index d0c724f53691..85c437b0cbc0 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -694,17 +694,8 @@ static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb,
694#endif /* CONFIG_CGROUP_WRITEBACK */ 694#endif /* CONFIG_CGROUP_WRITEBACK */
695 695
696struct sock; 696struct sock;
697#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
698void sock_update_memcg(struct sock *sk); 697void sock_update_memcg(struct sock *sk);
699void sock_release_memcg(struct sock *sk); 698void sock_release_memcg(struct sock *sk);
700#else
701static inline void sock_update_memcg(struct sock *sk)
702{
703}
704static inline void sock_release_memcg(struct sock *sk)
705{
706}
707#endif /* CONFIG_INET && CONFIG_MEMCG_KMEM */
708 699
709#ifdef CONFIG_MEMCG_KMEM 700#ifdef CONFIG_MEMCG_KMEM
710extern struct static_key memcg_kmem_enabled_key; 701extern struct static_key memcg_kmem_enabled_key;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 44ed2dee8f0c..d9344dad207e 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -293,46 +293,40 @@ static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
293 293
294void sock_update_memcg(struct sock *sk) 294void sock_update_memcg(struct sock *sk)
295{ 295{
296 if (mem_cgroup_sockets_enabled) { 296 struct mem_cgroup *memcg;
297 struct mem_cgroup *memcg; 297 struct cg_proto *cg_proto;
298 struct cg_proto *cg_proto;
299 298
300 BUG_ON(!sk->sk_prot->proto_cgroup); 299 BUG_ON(!sk->sk_prot->proto_cgroup);
301 300
302 /* Socket cloning can throw us here with sk_cgrp already 301 /* Socket cloning can throw us here with sk_cgrp already
303 * filled. It won't however, necessarily happen from 302 * filled. It won't however, necessarily happen from
304 * process context. So the test for root memcg given 303 * process context. So the test for root memcg given
305 * the current task's memcg won't help us in this case. 304 * the current task's memcg won't help us in this case.
306 * 305 *
307 * Respecting the original socket's memcg is a better 306 * Respecting the original socket's memcg is a better
308 * decision in this case. 307 * decision in this case.
309 */ 308 */
310 if (sk->sk_cgrp) { 309 if (sk->sk_cgrp) {
311 BUG_ON(mem_cgroup_is_root(sk->sk_cgrp->memcg)); 310 BUG_ON(mem_cgroup_is_root(sk->sk_cgrp->memcg));
312 css_get(&sk->sk_cgrp->memcg->css); 311 css_get(&sk->sk_cgrp->memcg->css);
313 return; 312 return;
314 } 313 }
315 314
316 rcu_read_lock(); 315 rcu_read_lock();
317 memcg = mem_cgroup_from_task(current); 316 memcg = mem_cgroup_from_task(current);
318 cg_proto = sk->sk_prot->proto_cgroup(memcg); 317 cg_proto = sk->sk_prot->proto_cgroup(memcg);
319 if (cg_proto && cg_proto->active && 318 if (cg_proto && cg_proto->active &&
320 css_tryget_online(&memcg->css)) { 319 css_tryget_online(&memcg->css)) {
321 sk->sk_cgrp = cg_proto; 320 sk->sk_cgrp = cg_proto;
322 }
323 rcu_read_unlock();
324 } 321 }
322 rcu_read_unlock();
325} 323}
326EXPORT_SYMBOL(sock_update_memcg); 324EXPORT_SYMBOL(sock_update_memcg);
327 325
328void sock_release_memcg(struct sock *sk) 326void sock_release_memcg(struct sock *sk)
329{ 327{
330 if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { 328 WARN_ON(!sk->sk_cgrp->memcg);
331 struct mem_cgroup *memcg; 329 css_put(&sk->sk_cgrp->memcg->css);
332 WARN_ON(!sk->sk_cgrp->memcg);
333 memcg = sk->sk_cgrp->memcg;
334 css_put(&sk->sk_cgrp->memcg->css);
335 }
336} 330}
337 331
338struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg) 332struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg)
diff --git a/net/core/sock.c b/net/core/sock.c
index 51270238e269..6c5dab01105b 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1507,12 +1507,6 @@ void sk_free(struct sock *sk)
1507} 1507}
1508EXPORT_SYMBOL(sk_free); 1508EXPORT_SYMBOL(sk_free);
1509 1509
1510static void sk_update_clone(const struct sock *sk, struct sock *newsk)
1511{
1512 if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
1513 sock_update_memcg(newsk);
1514}
1515
1516/** 1510/**
1517 * sk_clone_lock - clone a socket, and lock its clone 1511 * sk_clone_lock - clone a socket, and lock its clone
1518 * @sk: the socket to clone 1512 * @sk: the socket to clone
@@ -1607,7 +1601,8 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
1607 sk_set_socket(newsk, NULL); 1601 sk_set_socket(newsk, NULL);
1608 newsk->sk_wq = NULL; 1602 newsk->sk_wq = NULL;
1609 1603
1610 sk_update_clone(sk, newsk); 1604 if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
1605 sock_update_memcg(newsk);
1611 1606
1612 if (newsk->sk_prot->sockets_allocated) 1607 if (newsk->sk_prot->sockets_allocated)
1613 sk_sockets_allocated_inc(newsk); 1608 sk_sockets_allocated_inc(newsk);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 7bb1b091efd1..fd17eec93525 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -422,7 +422,8 @@ void tcp_init_sock(struct sock *sk)
422 sk->sk_rcvbuf = sysctl_tcp_rmem[1]; 422 sk->sk_rcvbuf = sysctl_tcp_rmem[1];
423 423
424 local_bh_disable(); 424 local_bh_disable();
425 sock_update_memcg(sk); 425 if (mem_cgroup_sockets_enabled)
426 sock_update_memcg(sk);
426 sk_sockets_allocated_inc(sk); 427 sk_sockets_allocated_inc(sk);
427 local_bh_enable(); 428 local_bh_enable();
428} 429}
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 65947c1f4733..eb39e02899e5 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1818,7 +1818,9 @@ void tcp_v4_destroy_sock(struct sock *sk)
1818 tcp_saved_syn_free(tp); 1818 tcp_saved_syn_free(tp);
1819 1819
1820 sk_sockets_allocated_dec(sk); 1820 sk_sockets_allocated_dec(sk);
1821 sock_release_memcg(sk); 1821
1822 if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
1823 sock_release_memcg(sk);
1822} 1824}
1823EXPORT_SYMBOL(tcp_v4_destroy_sock); 1825EXPORT_SYMBOL(tcp_v4_destroy_sock);
1824 1826