aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/tcp.h
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-08-25 05:27:49 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-25 05:27:49 -0400
commitad1af0fedba14f82b240a03fe20eb9b2fdbd0357 (patch)
tree4d53aa8bc2d9df782aa792e52670ab55c7a44d5b /include/net/tcp.h
parentb2bc85631e72485b984bcd202a104591874babba (diff)
tcp: Combat per-cpu skew in orphan tests.
As reported by Anton Blanchard when we use percpu_counter_read_positive() to make our orphan socket limit checks, the check can be off by up to num_cpus_online() * batch (which is 32 by default) which on a 128 cpu machine can be as large as the default orphan limit itself. Fix this by doing the full expensive sum check if the optimized check triggers. Reported-by: Anton Blanchard <anton@samba.org> Signed-off-by: David S. Miller <davem@davemloft.net> Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r--include/net/tcp.h18
1 files changed, 14 insertions, 4 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index df6a2eb20193..eaa9582779d0 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -268,11 +268,21 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
268 return seq3 - seq2 >= seq1 - seq2; 268 return seq3 - seq2 >= seq1 - seq2;
269} 269}
270 270
271static inline int tcp_too_many_orphans(struct sock *sk, int num) 271static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
272{ 272{
273 return (num > sysctl_tcp_max_orphans) || 273 struct percpu_counter *ocp = sk->sk_prot->orphan_count;
274 (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && 274 int orphans = percpu_counter_read_positive(ocp);
275 atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]); 275
276 if (orphans << shift > sysctl_tcp_max_orphans) {
277 orphans = percpu_counter_sum_positive(ocp);
278 if (orphans << shift > sysctl_tcp_max_orphans)
279 return true;
280 }
281
282 if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
283 atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])
284 return true;
285 return false;
276} 286}
277 287
278/* syncookies: remember time of last synqueue overflow */ 288/* syncookies: remember time of last synqueue overflow */