aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/sock.c
diff options
context:
space:
mode:
authorGlauber Costa <glommer@parallels.com>2012-01-19 23:57:16 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-22 15:08:46 -0500
commit0e90b31f4ba77027a7c21cbfc66404df0851ca21 (patch)
tree10dc6c443e2f058869d3953a90e6d48fb53f83ae /net/core/sock.c
parent8cfd14ad1eb52e44cb1fe7b47a68126e45e04026 (diff)
net: introduce res_counter_charge_nofail() for socket allocations
There is a case in __sk_mem_schedule(), where an allocation is beyond the maximum, but yet we are allowed to proceed. It happens under the following condition: sk->sk_wmem_queued + size >= sk->sk_sndbuf The network code won't revert the allocation in this case, meaning that at some point later it'll try to do it. Since this is never communicated to the underlying res_counter code, there is an inbalance in res_counter uncharge operation. I see two ways of fixing this: 1) storing the information about those allocations somewhere in memcg, and then deducting from that first, before we start draining the res_counter, 2) providing a slightly different allocation function for the res_counter, that matches the original behavior of the network code more closely. I decided to go for #2 here, believing it to be more elegant, since #1 would require us to do basically that, but in a more obscure way. Signed-off-by: Glauber Costa <glommer@parallels.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@suse.cz> CC: Tejun Heo <tj@kernel.org> CC: Li Zefan <lizf@cn.fujitsu.com> CC: Laurent Chavey <chavey@google.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/sock.c')
-rw-r--r--net/core/sock.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index 5c5af9988f94..3e81fd2e3c75 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1827,7 +1827,7 @@ suppress_allocation:
1827 /* Alas. Undo changes. */ 1827 /* Alas. Undo changes. */
1828 sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM; 1828 sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM;
1829 1829
1830 sk_memory_allocated_sub(sk, amt, parent_status); 1830 sk_memory_allocated_sub(sk, amt);
1831 1831
1832 return 0; 1832 return 0;
1833} 1833}
@@ -1840,7 +1840,7 @@ EXPORT_SYMBOL(__sk_mem_schedule);
1840void __sk_mem_reclaim(struct sock *sk) 1840void __sk_mem_reclaim(struct sock *sk)
1841{ 1841{
1842 sk_memory_allocated_sub(sk, 1842 sk_memory_allocated_sub(sk,
1843 sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, 0); 1843 sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT);
1844 sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1; 1844 sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1;
1845 1845
1846 if (sk_under_memory_pressure(sk) && 1846 if (sk_under_memory_pressure(sk) &&