Commit 8d987e5c authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

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: default avatarEric Dumazet <eric.dumazet@gmail.com>
Reported-by: default avatarRobin Holt <holt@sgi.com>
Reviewed-by: default avatarRobin Holt <holt@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 67286640
...@@ -225,7 +225,7 @@ extern int decnet_di_count; ...@@ -225,7 +225,7 @@ extern int decnet_di_count;
extern int decnet_dr_count; extern int decnet_dr_count;
extern int decnet_no_fc_max_cwnd; extern int decnet_no_fc_max_cwnd;
extern int sysctl_decnet_mem[3]; extern long sysctl_decnet_mem[3];
extern int sysctl_decnet_wmem[3]; extern int sysctl_decnet_wmem[3];
extern int sysctl_decnet_rmem[3]; extern int sysctl_decnet_rmem[3];
......
...@@ -762,7 +762,7 @@ struct proto { ...@@ -762,7 +762,7 @@ struct proto {
/* Memory pressure */ /* Memory pressure */
void (*enter_memory_pressure)(struct sock *sk); void (*enter_memory_pressure)(struct sock *sk);
atomic_t *memory_allocated; /* Current allocated memory. */ atomic_long_t *memory_allocated; /* Current allocated memory. */
struct percpu_counter *sockets_allocated; /* Current number of sockets. */ struct percpu_counter *sockets_allocated; /* Current number of sockets. */
/* /*
* Pressure flag: try to collapse. * Pressure flag: try to collapse.
...@@ -771,7 +771,7 @@ struct proto { ...@@ -771,7 +771,7 @@ struct proto {
* is strict, actions are advisory and have some latency. * is strict, actions are advisory and have some latency.
*/ */
int *memory_pressure; int *memory_pressure;
int *sysctl_mem; long *sysctl_mem;
int *sysctl_wmem; int *sysctl_wmem;
int *sysctl_rmem; int *sysctl_rmem;
int max_header; int max_header;
......
...@@ -224,7 +224,7 @@ extern int sysctl_tcp_fack; ...@@ -224,7 +224,7 @@ extern int sysctl_tcp_fack;
extern int sysctl_tcp_reordering; extern int sysctl_tcp_reordering;
extern int sysctl_tcp_ecn; extern int sysctl_tcp_ecn;
extern int sysctl_tcp_dsack; extern int sysctl_tcp_dsack;
extern int sysctl_tcp_mem[3]; extern long sysctl_tcp_mem[3];
extern int sysctl_tcp_wmem[3]; extern int sysctl_tcp_wmem[3];
extern int sysctl_tcp_rmem[3]; extern int sysctl_tcp_rmem[3];
extern int sysctl_tcp_app_win; extern int sysctl_tcp_app_win;
...@@ -247,7 +247,7 @@ extern int sysctl_tcp_cookie_size; ...@@ -247,7 +247,7 @@ extern int sysctl_tcp_cookie_size;
extern int sysctl_tcp_thin_linear_timeouts; extern int sysctl_tcp_thin_linear_timeouts;
extern int sysctl_tcp_thin_dupack; extern int sysctl_tcp_thin_dupack;
extern atomic_t tcp_memory_allocated; extern atomic_long_t tcp_memory_allocated;
extern struct percpu_counter tcp_sockets_allocated; extern struct percpu_counter tcp_sockets_allocated;
extern int tcp_memory_pressure; extern int tcp_memory_pressure;
...@@ -280,7 +280,7 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift) ...@@ -280,7 +280,7 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
} }
if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) atomic_long_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])
return true; return true;
return false; return false;
} }
......
...@@ -105,10 +105,10 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table, ...@@ -105,10 +105,10 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table,
extern struct proto udp_prot; extern struct proto udp_prot;
extern atomic_t udp_memory_allocated; extern atomic_long_t udp_memory_allocated;
/* sysctl variables for udp */ /* sysctl variables for udp */
extern int sysctl_udp_mem[3]; extern long sysctl_udp_mem[3];
extern int sysctl_udp_rmem_min; extern int sysctl_udp_rmem_min;
extern int sysctl_udp_wmem_min; extern int sysctl_udp_wmem_min;
......
...@@ -1653,10 +1653,10 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) ...@@ -1653,10 +1653,10 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind)
{ {
struct proto *prot = sk->sk_prot; struct proto *prot = sk->sk_prot;
int amt = sk_mem_pages(size); int amt = sk_mem_pages(size);
int allocated; long allocated;
sk->sk_forward_alloc += amt * SK_MEM_QUANTUM; sk->sk_forward_alloc += amt * SK_MEM_QUANTUM;
allocated = atomic_add_return(amt, prot->memory_allocated); allocated = atomic_long_add_return(amt, prot->memory_allocated);
/* Under limit. */ /* Under limit. */
if (allocated <= prot->sysctl_mem[0]) { if (allocated <= prot->sysctl_mem[0]) {
...@@ -1714,7 +1714,7 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) ...@@ -1714,7 +1714,7 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind)
/* Alas. Undo changes. */ /* Alas. Undo changes. */
sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM; sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM;
atomic_sub(amt, prot->memory_allocated); atomic_long_sub(amt, prot->memory_allocated);
return 0; return 0;
} }
EXPORT_SYMBOL(__sk_mem_schedule); EXPORT_SYMBOL(__sk_mem_schedule);
...@@ -1727,12 +1727,12 @@ void __sk_mem_reclaim(struct sock *sk) ...@@ -1727,12 +1727,12 @@ void __sk_mem_reclaim(struct sock *sk)
{ {
struct proto *prot = sk->sk_prot; struct proto *prot = sk->sk_prot;
atomic_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, atomic_long_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT,
prot->memory_allocated); prot->memory_allocated);
sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1; sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1;
if (prot->memory_pressure && *prot->memory_pressure && if (prot->memory_pressure && *prot->memory_pressure &&
(atomic_read(prot->memory_allocated) < prot->sysctl_mem[0])) (atomic_long_read(prot->memory_allocated) < prot->sysctl_mem[0]))
*prot->memory_pressure = 0; *prot->memory_pressure = 0;
} }
EXPORT_SYMBOL(__sk_mem_reclaim); EXPORT_SYMBOL(__sk_mem_reclaim);
...@@ -2452,12 +2452,12 @@ static char proto_method_implemented(const void *method) ...@@ -2452,12 +2452,12 @@ static char proto_method_implemented(const void *method)
static void proto_seq_printf(struct seq_file *seq, struct proto *proto) static void proto_seq_printf(struct seq_file *seq, struct proto *proto)
{ {
seq_printf(seq, "%-9s %4u %6d %6d %-3s %6u %-3s %-10s " seq_printf(seq, "%-9s %4u %6d %6ld %-3s %6u %-3s %-10s "
"%2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c\n", "%2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c\n",
proto->name, proto->name,
proto->obj_size, proto->obj_size,
sock_prot_inuse_get(seq_file_net(seq), proto), sock_prot_inuse_get(seq_file_net(seq), proto),
proto->memory_allocated != NULL ? atomic_read(proto->memory_allocated) : -1, proto->memory_allocated != NULL ? atomic_long_read(proto->memory_allocated) : -1L,
proto->memory_pressure != NULL ? *proto->memory_pressure ? "yes" : "no" : "NI", proto->memory_pressure != NULL ? *proto->memory_pressure ? "yes" : "no" : "NI",
proto->max_header, proto->max_header,
proto->slab == NULL ? "no" : "yes", proto->slab == NULL ? "no" : "yes",
......
...@@ -155,7 +155,7 @@ static const struct proto_ops dn_proto_ops; ...@@ -155,7 +155,7 @@ static const struct proto_ops dn_proto_ops;
static DEFINE_RWLOCK(dn_hash_lock); static DEFINE_RWLOCK(dn_hash_lock);
static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE]; static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
static struct hlist_head dn_wild_sk; static struct hlist_head dn_wild_sk;
static atomic_t decnet_memory_allocated; static atomic_long_t decnet_memory_allocated;
static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags); static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags);
static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags); static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
......
...@@ -38,7 +38,7 @@ int decnet_log_martians = 1; ...@@ -38,7 +38,7 @@ int decnet_log_martians = 1;
int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW; int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW;
/* Reasonable defaults, I hope, based on tcp's defaults */ /* Reasonable defaults, I hope, based on tcp's defaults */
int sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 }; long sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 };
int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 };
...@@ -324,7 +324,7 @@ static ctl_table dn_table[] = { ...@@ -324,7 +324,7 @@ static ctl_table dn_table[] = {
.data = &sysctl_decnet_mem, .data = &sysctl_decnet_mem,
.maxlen = sizeof(sysctl_decnet_mem), .maxlen = sizeof(sysctl_decnet_mem),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_doulongvec_minmax
}, },
{ {
.procname = "decnet_rmem", .procname = "decnet_rmem",
......
...@@ -59,13 +59,13 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) ...@@ -59,13 +59,13 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
local_bh_enable(); local_bh_enable();
socket_seq_show(seq); socket_seq_show(seq);
seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n",
sock_prot_inuse_get(net, &tcp_prot), orphans, sock_prot_inuse_get(net, &tcp_prot), orphans,
tcp_death_row.tw_count, sockets, tcp_death_row.tw_count, sockets,
atomic_read(&tcp_memory_allocated)); atomic_long_read(&tcp_memory_allocated));
seq_printf(seq, "UDP: inuse %d mem %d\n", seq_printf(seq, "UDP: inuse %d mem %ld\n",
sock_prot_inuse_get(net, &udp_prot), sock_prot_inuse_get(net, &udp_prot),
atomic_read(&udp_memory_allocated)); atomic_long_read(&udp_memory_allocated));
seq_printf(seq, "UDPLITE: inuse %d\n", seq_printf(seq, "UDPLITE: inuse %d\n",
sock_prot_inuse_get(net, &udplite_prot)); sock_prot_inuse_get(net, &udplite_prot));
seq_printf(seq, "RAW: inuse %d\n", seq_printf(seq, "RAW: inuse %d\n",
......
...@@ -398,7 +398,7 @@ static struct ctl_table ipv4_table[] = { ...@@ -398,7 +398,7 @@ static struct ctl_table ipv4_table[] = {
.data = &sysctl_tcp_mem, .data = &sysctl_tcp_mem,
.maxlen = sizeof(sysctl_tcp_mem), .maxlen = sizeof(sysctl_tcp_mem),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec .proc_handler = proc_doulongvec_minmax
}, },
{ {
.procname = "tcp_wmem", .procname = "tcp_wmem",
...@@ -602,8 +602,7 @@ static struct ctl_table ipv4_table[] = { ...@@ -602,8 +602,7 @@ static struct ctl_table ipv4_table[] = {
.data = &sysctl_udp_mem, .data = &sysctl_udp_mem,
.maxlen = sizeof(sysctl_udp_mem), .maxlen = sizeof(sysctl_udp_mem),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec_minmax, .proc_handler = proc_doulongvec_minmax,
.extra1 = &zero
}, },
{ {
.procname = "udp_rmem_min", .procname = "udp_rmem_min",
......
...@@ -282,7 +282,7 @@ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; ...@@ -282,7 +282,7 @@ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
struct percpu_counter tcp_orphan_count; struct percpu_counter tcp_orphan_count;
EXPORT_SYMBOL_GPL(tcp_orphan_count); EXPORT_SYMBOL_GPL(tcp_orphan_count);
int sysctl_tcp_mem[3] __read_mostly; long sysctl_tcp_mem[3] __read_mostly;
int sysctl_tcp_wmem[3] __read_mostly; int sysctl_tcp_wmem[3] __read_mostly;
int sysctl_tcp_rmem[3] __read_mostly; int sysctl_tcp_rmem[3] __read_mostly;
...@@ -290,7 +290,7 @@ EXPORT_SYMBOL(sysctl_tcp_mem); ...@@ -290,7 +290,7 @@ EXPORT_SYMBOL(sysctl_tcp_mem);
EXPORT_SYMBOL(sysctl_tcp_rmem); EXPORT_SYMBOL(sysctl_tcp_rmem);
EXPORT_SYMBOL(sysctl_tcp_wmem); EXPORT_SYMBOL(sysctl_tcp_wmem);
atomic_t tcp_memory_allocated; /* Current allocated memory. */ atomic_long_t tcp_memory_allocated; /* Current allocated memory. */
EXPORT_SYMBOL(tcp_memory_allocated); EXPORT_SYMBOL(tcp_memory_allocated);
/* /*
......
...@@ -259,8 +259,11 @@ static void tcp_fixup_sndbuf(struct sock *sk) ...@@ -259,8 +259,11 @@ static void tcp_fixup_sndbuf(struct sock *sk)
int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 + int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 +
sizeof(struct sk_buff); sizeof(struct sk_buff);
if (sk->sk_sndbuf < 3 * sndmem) if (sk->sk_sndbuf < 3 * sndmem) {
sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); sk->sk_sndbuf = 3 * sndmem;
if (sk->sk_sndbuf > sysctl_tcp_wmem[2])
sk->sk_sndbuf = sysctl_tcp_wmem[2];
}
} }
/* 2. Tuning advertised window (window_clamp, rcv_ssthresh) /* 2. Tuning advertised window (window_clamp, rcv_ssthresh)
...@@ -396,7 +399,7 @@ static void tcp_clamp_window(struct sock *sk) ...@@ -396,7 +399,7 @@ static void tcp_clamp_window(struct sock *sk)
if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] &&
!(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
!tcp_memory_pressure && !tcp_memory_pressure &&
atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc),
sysctl_tcp_rmem[2]); sysctl_tcp_rmem[2]);
} }
...@@ -4861,7 +4864,7 @@ static int tcp_should_expand_sndbuf(struct sock *sk) ...@@ -4861,7 +4864,7 @@ static int tcp_should_expand_sndbuf(struct sock *sk)
return 0; return 0;
/* If we are under soft global TCP memory pressure, do not expand. */ /* If we are under soft global TCP memory pressure, do not expand. */
if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0])
return 0; return 0;
/* If we filled the congestion window, do not expand. */ /* If we filled the congestion window, do not expand. */
......
...@@ -110,7 +110,7 @@ ...@@ -110,7 +110,7 @@
struct udp_table udp_table __read_mostly; struct udp_table udp_table __read_mostly;
EXPORT_SYMBOL(udp_table); EXPORT_SYMBOL(udp_table);
int sysctl_udp_mem[3] __read_mostly; long sysctl_udp_mem[3] __read_mostly;
EXPORT_SYMBOL(sysctl_udp_mem); EXPORT_SYMBOL(sysctl_udp_mem);
int sysctl_udp_rmem_min __read_mostly; int sysctl_udp_rmem_min __read_mostly;
...@@ -119,7 +119,7 @@ EXPORT_SYMBOL(sysctl_udp_rmem_min); ...@@ -119,7 +119,7 @@ EXPORT_SYMBOL(sysctl_udp_rmem_min);
int sysctl_udp_wmem_min __read_mostly; int sysctl_udp_wmem_min __read_mostly;
EXPORT_SYMBOL(sysctl_udp_wmem_min); EXPORT_SYMBOL(sysctl_udp_wmem_min);
atomic_t udp_memory_allocated; atomic_long_t udp_memory_allocated;
EXPORT_SYMBOL(udp_memory_allocated); EXPORT_SYMBOL(udp_memory_allocated);
#define MAX_UDP_PORTS 65536 #define MAX_UDP_PORTS 65536
......
...@@ -92,7 +92,7 @@ static struct sctp_af *sctp_af_v6_specific; ...@@ -92,7 +92,7 @@ static struct sctp_af *sctp_af_v6_specific;
struct kmem_cache *sctp_chunk_cachep __read_mostly; struct kmem_cache *sctp_chunk_cachep __read_mostly;
struct kmem_cache *sctp_bucket_cachep __read_mostly; struct kmem_cache *sctp_bucket_cachep __read_mostly;
int sysctl_sctp_mem[3]; long sysctl_sctp_mem[3];
int sysctl_sctp_rmem[3]; int sysctl_sctp_rmem[3];
int sysctl_sctp_wmem[3]; int sysctl_sctp_wmem[3];
......
...@@ -111,12 +111,12 @@ static void sctp_sock_migrate(struct sock *, struct sock *, ...@@ -111,12 +111,12 @@ static void sctp_sock_migrate(struct sock *, struct sock *,
static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG;
extern struct kmem_cache *sctp_bucket_cachep; extern struct kmem_cache *sctp_bucket_cachep;
extern int sysctl_sctp_mem[3]; extern long sysctl_sctp_mem[3];
extern int sysctl_sctp_rmem[3]; extern int sysctl_sctp_rmem[3];
extern int sysctl_sctp_wmem[3]; extern int sysctl_sctp_wmem[3];
static int sctp_memory_pressure; static int sctp_memory_pressure;
static atomic_t sctp_memory_allocated; static atomic_long_t sctp_memory_allocated;
struct percpu_counter sctp_sockets_allocated; struct percpu_counter sctp_sockets_allocated;
static void sctp_enter_memory_pressure(struct sock *sk) static void sctp_enter_memory_pressure(struct sock *sk)
......
...@@ -54,7 +54,7 @@ static int sack_timer_max = 500; ...@@ -54,7 +54,7 @@ static int sack_timer_max = 500;
static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
static int rwnd_scale_max = 16; static int rwnd_scale_max = 16;
extern int sysctl_sctp_mem[3]; extern long sysctl_sctp_mem[3];
extern int sysctl_sctp_rmem[3]; extern int sysctl_sctp_rmem[3];
extern int sysctl_sctp_wmem[3]; extern int sysctl_sctp_wmem[3];
...@@ -203,7 +203,7 @@ static ctl_table sctp_table[] = { ...@@ -203,7 +203,7 @@ static ctl_table sctp_table[] = {
.data = &sysctl_sctp_mem, .data = &sysctl_sctp_mem,
.maxlen = sizeof(sysctl_sctp_mem), .maxlen = sizeof(sysctl_sctp_mem),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_doulongvec_minmax
}, },
{ {
.procname = "sctp_rmem", .procname = "sctp_rmem",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment