Commit 8d987e5c75107ca7515fa19e857cfa24aab6ec8f
Committed by
David S. Miller
1 parent
67286640f6
Exists in
master
and in
39 other branches
net: avoid limits overflow
Robin Holt tried to boot a 16TB machine and found some limits were reached : sysctl_tcp_mem[2], sysctl_udp_mem[2] We can switch infrastructure to use long "instead" of "int", now atomic_long_t primitives are available for free. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Reported-by: Robin Holt <holt@sgi.com> Reviewed-by: Robin Holt <holt@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 15 changed files with 40 additions and 38 deletions Side-by-side Diff
include/net/dn.h
include/net/sock.h
... | ... | @@ -762,7 +762,7 @@ |
762 | 762 | |
763 | 763 | /* Memory pressure */ |
764 | 764 | void (*enter_memory_pressure)(struct sock *sk); |
765 | - atomic_t *memory_allocated; /* Current allocated memory. */ | |
765 | + atomic_long_t *memory_allocated; /* Current allocated memory. */ | |
766 | 766 | struct percpu_counter *sockets_allocated; /* Current number of sockets. */ |
767 | 767 | /* |
768 | 768 | * Pressure flag: try to collapse. |
... | ... | @@ -771,7 +771,7 @@ |
771 | 771 | * is strict, actions are advisory and have some latency. |
772 | 772 | */ |
773 | 773 | int *memory_pressure; |
774 | - int *sysctl_mem; | |
774 | + long *sysctl_mem; | |
775 | 775 | int *sysctl_wmem; |
776 | 776 | int *sysctl_rmem; |
777 | 777 | int max_header; |
include/net/tcp.h
... | ... | @@ -224,7 +224,7 @@ |
224 | 224 | extern int sysctl_tcp_reordering; |
225 | 225 | extern int sysctl_tcp_ecn; |
226 | 226 | extern int sysctl_tcp_dsack; |
227 | -extern int sysctl_tcp_mem[3]; | |
227 | +extern long sysctl_tcp_mem[3]; | |
228 | 228 | extern int sysctl_tcp_wmem[3]; |
229 | 229 | extern int sysctl_tcp_rmem[3]; |
230 | 230 | extern int sysctl_tcp_app_win; |
... | ... | @@ -247,7 +247,7 @@ |
247 | 247 | extern int sysctl_tcp_thin_linear_timeouts; |
248 | 248 | extern int sysctl_tcp_thin_dupack; |
249 | 249 | |
250 | -extern atomic_t tcp_memory_allocated; | |
250 | +extern atomic_long_t tcp_memory_allocated; | |
251 | 251 | extern struct percpu_counter tcp_sockets_allocated; |
252 | 252 | extern int tcp_memory_pressure; |
253 | 253 | |
... | ... | @@ -280,7 +280,7 @@ |
280 | 280 | } |
281 | 281 | |
282 | 282 | if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && |
283 | - atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) | |
283 | + atomic_long_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) | |
284 | 284 | return true; |
285 | 285 | return false; |
286 | 286 | } |
include/net/udp.h
... | ... | @@ -105,10 +105,10 @@ |
105 | 105 | |
106 | 106 | extern struct proto udp_prot; |
107 | 107 | |
108 | -extern atomic_t udp_memory_allocated; | |
108 | +extern atomic_long_t udp_memory_allocated; | |
109 | 109 | |
110 | 110 | /* sysctl variables for udp */ |
111 | -extern int sysctl_udp_mem[3]; | |
111 | +extern long sysctl_udp_mem[3]; | |
112 | 112 | extern int sysctl_udp_rmem_min; |
113 | 113 | extern int sysctl_udp_wmem_min; |
114 | 114 |
net/core/sock.c
... | ... | @@ -1653,10 +1653,10 @@ |
1653 | 1653 | { |
1654 | 1654 | struct proto *prot = sk->sk_prot; |
1655 | 1655 | int amt = sk_mem_pages(size); |
1656 | - int allocated; | |
1656 | + long allocated; | |
1657 | 1657 | |
1658 | 1658 | sk->sk_forward_alloc += amt * SK_MEM_QUANTUM; |
1659 | - allocated = atomic_add_return(amt, prot->memory_allocated); | |
1659 | + allocated = atomic_long_add_return(amt, prot->memory_allocated); | |
1660 | 1660 | |
1661 | 1661 | /* Under limit. */ |
1662 | 1662 | if (allocated <= prot->sysctl_mem[0]) { |
... | ... | @@ -1714,7 +1714,7 @@ |
1714 | 1714 | |
1715 | 1715 | /* Alas. Undo changes. */ |
1716 | 1716 | sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM; |
1717 | - atomic_sub(amt, prot->memory_allocated); | |
1717 | + atomic_long_sub(amt, prot->memory_allocated); | |
1718 | 1718 | return 0; |
1719 | 1719 | } |
1720 | 1720 | EXPORT_SYMBOL(__sk_mem_schedule); |
1721 | 1721 | |
... | ... | @@ -1727,12 +1727,12 @@ |
1727 | 1727 | { |
1728 | 1728 | struct proto *prot = sk->sk_prot; |
1729 | 1729 | |
1730 | - atomic_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, | |
1730 | + atomic_long_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, | |
1731 | 1731 | prot->memory_allocated); |
1732 | 1732 | sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1; |
1733 | 1733 | |
1734 | 1734 | if (prot->memory_pressure && *prot->memory_pressure && |
1735 | - (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0])) | |
1735 | + (atomic_long_read(prot->memory_allocated) < prot->sysctl_mem[0])) | |
1736 | 1736 | *prot->memory_pressure = 0; |
1737 | 1737 | } |
1738 | 1738 | EXPORT_SYMBOL(__sk_mem_reclaim); |
1739 | 1739 | |
... | ... | @@ -2452,12 +2452,12 @@ |
2452 | 2452 | |
2453 | 2453 | static void proto_seq_printf(struct seq_file *seq, struct proto *proto) |
2454 | 2454 | { |
2455 | - seq_printf(seq, "%-9s %4u %6d %6d %-3s %6u %-3s %-10s " | |
2455 | + seq_printf(seq, "%-9s %4u %6d %6ld %-3s %6u %-3s %-10s " | |
2456 | 2456 | "%2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c\n", |
2457 | 2457 | proto->name, |
2458 | 2458 | proto->obj_size, |
2459 | 2459 | sock_prot_inuse_get(seq_file_net(seq), proto), |
2460 | - proto->memory_allocated != NULL ? atomic_read(proto->memory_allocated) : -1, | |
2460 | + proto->memory_allocated != NULL ? atomic_long_read(proto->memory_allocated) : -1L, | |
2461 | 2461 | proto->memory_pressure != NULL ? *proto->memory_pressure ? "yes" : "no" : "NI", |
2462 | 2462 | proto->max_header, |
2463 | 2463 | proto->slab == NULL ? "no" : "yes", |
net/decnet/af_decnet.c
... | ... | @@ -155,7 +155,7 @@ |
155 | 155 | static DEFINE_RWLOCK(dn_hash_lock); |
156 | 156 | static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE]; |
157 | 157 | static struct hlist_head dn_wild_sk; |
158 | -static atomic_t decnet_memory_allocated; | |
158 | +static atomic_long_t decnet_memory_allocated; | |
159 | 159 | |
160 | 160 | static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags); |
161 | 161 | static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags); |
net/decnet/sysctl_net_decnet.c
... | ... | @@ -38,7 +38,7 @@ |
38 | 38 | int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW; |
39 | 39 | |
40 | 40 | /* Reasonable defaults, I hope, based on tcp's defaults */ |
41 | -int sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 }; | |
41 | +long sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 }; | |
42 | 42 | int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; |
43 | 43 | int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; |
44 | 44 | |
... | ... | @@ -324,7 +324,7 @@ |
324 | 324 | .data = &sysctl_decnet_mem, |
325 | 325 | .maxlen = sizeof(sysctl_decnet_mem), |
326 | 326 | .mode = 0644, |
327 | - .proc_handler = proc_dointvec, | |
327 | + .proc_handler = proc_doulongvec_minmax | |
328 | 328 | }, |
329 | 329 | { |
330 | 330 | .procname = "decnet_rmem", |
net/ipv4/proc.c
... | ... | @@ -59,13 +59,13 @@ |
59 | 59 | local_bh_enable(); |
60 | 60 | |
61 | 61 | socket_seq_show(seq); |
62 | - seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", | |
62 | + seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n", | |
63 | 63 | sock_prot_inuse_get(net, &tcp_prot), orphans, |
64 | 64 | tcp_death_row.tw_count, sockets, |
65 | - atomic_read(&tcp_memory_allocated)); | |
66 | - seq_printf(seq, "UDP: inuse %d mem %d\n", | |
65 | + atomic_long_read(&tcp_memory_allocated)); | |
66 | + seq_printf(seq, "UDP: inuse %d mem %ld\n", | |
67 | 67 | sock_prot_inuse_get(net, &udp_prot), |
68 | - atomic_read(&udp_memory_allocated)); | |
68 | + atomic_long_read(&udp_memory_allocated)); | |
69 | 69 | seq_printf(seq, "UDPLITE: inuse %d\n", |
70 | 70 | sock_prot_inuse_get(net, &udplite_prot)); |
71 | 71 | seq_printf(seq, "RAW: inuse %d\n", |
net/ipv4/sysctl_net_ipv4.c
... | ... | @@ -398,7 +398,7 @@ |
398 | 398 | .data = &sysctl_tcp_mem, |
399 | 399 | .maxlen = sizeof(sysctl_tcp_mem), |
400 | 400 | .mode = 0644, |
401 | - .proc_handler = proc_dointvec | |
401 | + .proc_handler = proc_doulongvec_minmax | |
402 | 402 | }, |
403 | 403 | { |
404 | 404 | .procname = "tcp_wmem", |
... | ... | @@ -602,8 +602,7 @@ |
602 | 602 | .data = &sysctl_udp_mem, |
603 | 603 | .maxlen = sizeof(sysctl_udp_mem), |
604 | 604 | .mode = 0644, |
605 | - .proc_handler = proc_dointvec_minmax, | |
606 | - .extra1 = &zero | |
605 | + .proc_handler = proc_doulongvec_minmax, | |
607 | 606 | }, |
608 | 607 | { |
609 | 608 | .procname = "udp_rmem_min", |
net/ipv4/tcp.c
... | ... | @@ -282,7 +282,7 @@ |
282 | 282 | struct percpu_counter tcp_orphan_count; |
283 | 283 | EXPORT_SYMBOL_GPL(tcp_orphan_count); |
284 | 284 | |
285 | -int sysctl_tcp_mem[3] __read_mostly; | |
285 | +long sysctl_tcp_mem[3] __read_mostly; | |
286 | 286 | int sysctl_tcp_wmem[3] __read_mostly; |
287 | 287 | int sysctl_tcp_rmem[3] __read_mostly; |
288 | 288 | |
... | ... | @@ -290,7 +290,7 @@ |
290 | 290 | EXPORT_SYMBOL(sysctl_tcp_rmem); |
291 | 291 | EXPORT_SYMBOL(sysctl_tcp_wmem); |
292 | 292 | |
293 | -atomic_t tcp_memory_allocated; /* Current allocated memory. */ | |
293 | +atomic_long_t tcp_memory_allocated; /* Current allocated memory. */ | |
294 | 294 | EXPORT_SYMBOL(tcp_memory_allocated); |
295 | 295 | |
296 | 296 | /* |
net/ipv4/tcp_input.c
... | ... | @@ -259,8 +259,11 @@ |
259 | 259 | int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 + |
260 | 260 | sizeof(struct sk_buff); |
261 | 261 | |
262 | - if (sk->sk_sndbuf < 3 * sndmem) | |
263 | - sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); | |
262 | + if (sk->sk_sndbuf < 3 * sndmem) { | |
263 | + sk->sk_sndbuf = 3 * sndmem; | |
264 | + if (sk->sk_sndbuf > sysctl_tcp_wmem[2]) | |
265 | + sk->sk_sndbuf = sysctl_tcp_wmem[2]; | |
266 | + } | |
264 | 267 | } |
265 | 268 | |
266 | 269 | /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) |
... | ... | @@ -396,7 +399,7 @@ |
396 | 399 | if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && |
397 | 400 | !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && |
398 | 401 | !tcp_memory_pressure && |
399 | - atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { | |
402 | + atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { | |
400 | 403 | sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), |
401 | 404 | sysctl_tcp_rmem[2]); |
402 | 405 | } |
... | ... | @@ -4861,7 +4864,7 @@ |
4861 | 4864 | return 0; |
4862 | 4865 | |
4863 | 4866 | /* If we are under soft global TCP memory pressure, do not expand. */ |
4864 | - if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) | |
4867 | + if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) | |
4865 | 4868 | return 0; |
4866 | 4869 | |
4867 | 4870 | /* If we filled the congestion window, do not expand. */ |
net/ipv4/udp.c
... | ... | @@ -110,7 +110,7 @@ |
110 | 110 | struct udp_table udp_table __read_mostly; |
111 | 111 | EXPORT_SYMBOL(udp_table); |
112 | 112 | |
113 | -int sysctl_udp_mem[3] __read_mostly; | |
113 | +long sysctl_udp_mem[3] __read_mostly; | |
114 | 114 | EXPORT_SYMBOL(sysctl_udp_mem); |
115 | 115 | |
116 | 116 | int sysctl_udp_rmem_min __read_mostly; |
... | ... | @@ -119,7 +119,7 @@ |
119 | 119 | int sysctl_udp_wmem_min __read_mostly; |
120 | 120 | EXPORT_SYMBOL(sysctl_udp_wmem_min); |
121 | 121 | |
122 | -atomic_t udp_memory_allocated; | |
122 | +atomic_long_t udp_memory_allocated; | |
123 | 123 | EXPORT_SYMBOL(udp_memory_allocated); |
124 | 124 | |
125 | 125 | #define MAX_UDP_PORTS 65536 |
net/sctp/protocol.c
net/sctp/socket.c
... | ... | @@ -111,12 +111,12 @@ |
111 | 111 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; |
112 | 112 | |
113 | 113 | extern struct kmem_cache *sctp_bucket_cachep; |
114 | -extern int sysctl_sctp_mem[3]; | |
114 | +extern long sysctl_sctp_mem[3]; | |
115 | 115 | extern int sysctl_sctp_rmem[3]; |
116 | 116 | extern int sysctl_sctp_wmem[3]; |
117 | 117 | |
118 | 118 | static int sctp_memory_pressure; |
119 | -static atomic_t sctp_memory_allocated; | |
119 | +static atomic_long_t sctp_memory_allocated; | |
120 | 120 | struct percpu_counter sctp_sockets_allocated; |
121 | 121 | |
122 | 122 | static void sctp_enter_memory_pressure(struct sock *sk) |
net/sctp/sysctl.c
... | ... | @@ -54,7 +54,7 @@ |
54 | 54 | static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ |
55 | 55 | static int rwnd_scale_max = 16; |
56 | 56 | |
57 | -extern int sysctl_sctp_mem[3]; | |
57 | +extern long sysctl_sctp_mem[3]; | |
58 | 58 | extern int sysctl_sctp_rmem[3]; |
59 | 59 | extern int sysctl_sctp_wmem[3]; |
60 | 60 | |
... | ... | @@ -203,7 +203,7 @@ |
203 | 203 | .data = &sysctl_sctp_mem, |
204 | 204 | .maxlen = sizeof(sysctl_sctp_mem), |
205 | 205 | .mode = 0644, |
206 | - .proc_handler = proc_dointvec, | |
206 | + .proc_handler = proc_doulongvec_minmax | |
207 | 207 | }, |
208 | 208 | { |
209 | 209 | .procname = "sctp_rmem", |