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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -225,7 +225,7 @@ extern int decnet_di_count;
extern int decnet_dr_count;
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_rmem[3];

+2 −2
Original line number Diff line number Diff line
@@ -762,7 +762,7 @@ struct proto {

	/* Memory pressure */
	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. */
	/*
	 * Pressure flag: try to collapse.
@@ -771,7 +771,7 @@ struct proto {
	 * is strict, actions are advisory and have some latency.
	 */
	int			*memory_pressure;
	int			*sysctl_mem;
	long			*sysctl_mem;
	int			*sysctl_wmem;
	int			*sysctl_rmem;
	int			max_header;
+3 −3
Original line number Diff line number Diff line
@@ -224,7 +224,7 @@ extern int sysctl_tcp_fack;
extern int sysctl_tcp_reordering;
extern int sysctl_tcp_ecn;
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_rmem[3];
extern int sysctl_tcp_app_win;
@@ -247,7 +247,7 @@ extern int sysctl_tcp_cookie_size;
extern int sysctl_tcp_thin_linear_timeouts;
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 int tcp_memory_pressure;

@@ -280,7 +280,7 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
	}

	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 false;
}
+2 −2
Original line number Diff line number Diff line
@@ -105,10 +105,10 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table,

extern struct proto udp_prot;

extern atomic_t udp_memory_allocated;
extern atomic_long_t udp_memory_allocated;

/* 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_wmem_min;

+7 −7
Original line number Diff line number Diff line
@@ -1653,10 +1653,10 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind)
{
	struct proto *prot = sk->sk_prot;
	int amt = sk_mem_pages(size);
	int allocated;
	long allocated;

	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. */
	if (allocated <= prot->sysctl_mem[0]) {
@@ -1714,7 +1714,7 @@ suppress_allocation:

	/* Alas. Undo changes. */
	sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM;
	atomic_sub(amt, prot->memory_allocated);
	atomic_long_sub(amt, prot->memory_allocated);
	return 0;
}
EXPORT_SYMBOL(__sk_mem_schedule);
@@ -1727,12 +1727,12 @@ void __sk_mem_reclaim(struct sock *sk)
{
	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);
	sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1;

	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;
}
EXPORT_SYMBOL(__sk_mem_reclaim);
@@ -2452,12 +2452,12 @@ static char proto_method_implemented(const void *method)

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",
		   proto->name,
		   proto->obj_size,
		   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->max_header,
		   proto->slab == NULL ? "no" : "yes",
Loading