aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGlauber Costa <glommer@parallels.com>2011-12-11 16:47:03 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-12 19:04:10 -0500
commite1aab161e0135aafcd439be20b4f35e4b0922d95 (patch)
treed0bcdf7a34a34020079238027b431ffc6dece307 /net
parent180d8cd942ce336b2c869d324855c40c5db478ad (diff)
socket: initial cgroup code.
The goal of this work is to move the memory pressure tcp controls to a cgroup, instead of just relying on global conditions. To avoid excessive overhead in the network fast paths, the code that accounts allocated memory to a cgroup is hidden inside a static_branch(). This branch is patched out until the first non-root cgroup is created. So when nobody is using cgroups, even if it is mounted, no significant performance penalty should be seen. This patch handles the generic part of the code, and has nothing tcp-specific. Signed-off-by: Glauber Costa <glommer@parallels.com> Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujtsu.com> CC: Kirill A. Shutemov <kirill@shutemov.name> CC: David S. Miller <davem@davemloft.net> CC: Eric W. Biederman <ebiederm@xmission.com> CC: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/sock.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index a3d4205e7238..6a871b8fdd20 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -111,6 +111,7 @@
111#include <linux/init.h> 111#include <linux/init.h>
112#include <linux/highmem.h> 112#include <linux/highmem.h>
113#include <linux/user_namespace.h> 113#include <linux/user_namespace.h>
114#include <linux/jump_label.h>
114 115
115#include <asm/uaccess.h> 116#include <asm/uaccess.h>
116#include <asm/system.h> 117#include <asm/system.h>
@@ -142,6 +143,9 @@
142static struct lock_class_key af_family_keys[AF_MAX]; 143static struct lock_class_key af_family_keys[AF_MAX];
143static struct lock_class_key af_family_slock_keys[AF_MAX]; 144static struct lock_class_key af_family_slock_keys[AF_MAX];
144 145
146struct jump_label_key memcg_socket_limit_enabled;
147EXPORT_SYMBOL(memcg_socket_limit_enabled);
148
145/* 149/*
146 * Make lock validator output more readable. (we pre-construct these 150 * Make lock validator output more readable. (we pre-construct these
147 * strings build-time, so that runtime initialization of socket 151 * strings build-time, so that runtime initialization of socket
@@ -1711,23 +1715,27 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind)
1711 struct proto *prot = sk->sk_prot; 1715 struct proto *prot = sk->sk_prot;
1712 int amt = sk_mem_pages(size); 1716 int amt = sk_mem_pages(size);
1713 long allocated; 1717 long allocated;
1718 int parent_status = UNDER_LIMIT;
1714 1719
1715 sk->sk_forward_alloc += amt * SK_MEM_QUANTUM; 1720 sk->sk_forward_alloc += amt * SK_MEM_QUANTUM;
1716 1721
1717 allocated = sk_memory_allocated_add(sk, amt); 1722 allocated = sk_memory_allocated_add(sk, amt, &parent_status);
1718 1723
1719 /* Under limit. */ 1724 /* Under limit. */
1720 if (allocated <= sk_prot_mem_limits(sk, 0)) { 1725 if (parent_status == UNDER_LIMIT &&
1726 allocated <= sk_prot_mem_limits(sk, 0)) {
1721 sk_leave_memory_pressure(sk); 1727 sk_leave_memory_pressure(sk);
1722 return 1; 1728 return 1;
1723 } 1729 }
1724 1730
1725 /* Under pressure. */ 1731 /* Under pressure. (we or our parents) */
1726 if (allocated > sk_prot_mem_limits(sk, 1)) 1732 if ((parent_status > SOFT_LIMIT) ||
1733 allocated > sk_prot_mem_limits(sk, 1))
1727 sk_enter_memory_pressure(sk); 1734 sk_enter_memory_pressure(sk);
1728 1735
1729 /* Over hard limit. */ 1736 /* Over hard limit (we or our parents) */
1730 if (allocated > sk_prot_mem_limits(sk, 2)) 1737 if ((parent_status == OVER_LIMIT) ||
1738 (allocated > sk_prot_mem_limits(sk, 2)))
1731 goto suppress_allocation; 1739 goto suppress_allocation;
1732 1740
1733 /* guarantee minimum buffer size under pressure */ 1741 /* guarantee minimum buffer size under pressure */
@@ -1774,7 +1782,7 @@ suppress_allocation:
1774 /* Alas. Undo changes. */ 1782 /* Alas. Undo changes. */
1775 sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM; 1783 sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM;
1776 1784
1777 sk_memory_allocated_sub(sk, amt); 1785 sk_memory_allocated_sub(sk, amt, parent_status);
1778 1786
1779 return 0; 1787 return 0;
1780} 1788}
@@ -1787,7 +1795,7 @@ EXPORT_SYMBOL(__sk_mem_schedule);
1787void __sk_mem_reclaim(struct sock *sk) 1795void __sk_mem_reclaim(struct sock *sk)
1788{ 1796{
1789 sk_memory_allocated_sub(sk, 1797 sk_memory_allocated_sub(sk,
1790 sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT); 1798 sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, 0);
1791 sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1; 1799 sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1;
1792 1800
1793 if (sk_under_memory_pressure(sk) && 1801 if (sk_under_memory_pressure(sk) &&