diff options
| author | Eric Dumazet <edumazet@google.com> | 2013-02-02 05:23:16 +0000 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-02-03 16:00:25 -0500 | 
| commit | 973ec449bb4f2b8c514bacbcb4d9506fc31c8ce3 (patch) | |
| tree | 29d7b5de18aeff078f265f75a2a94be22254b851 /net/ipv4/tcp_cong.c | |
| parent | 59fa534874e6779082275d12d950e26c67c86498 (diff) | |
| download | olio-linux-3.10-973ec449bb4f2b8c514bacbcb4d9506fc31c8ce3.tar.xz olio-linux-3.10-973ec449bb4f2b8c514bacbcb4d9506fc31c8ce3.zip  | |
tcp: fix an infinite loop in tcp_slow_start()
Since commit 9dc274151a548 (tcp: fix ABC in tcp_slow_start()),
a nul snd_cwnd triggers an infinite loop in tcp_slow_start()
Avoid this infinite loop and log a one time error for further
analysis. FRTO code is suspected to cause this bug.
Reported-by: Pasi Kärkkäinen <pasik@iki.fi>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_cong.c')
| -rw-r--r-- | net/ipv4/tcp_cong.c | 14 | 
1 files changed, 10 insertions, 4 deletions
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 291f2ed7cc3..cdf2e707bb1 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c @@ -310,6 +310,12 @@ void tcp_slow_start(struct tcp_sock *tp)  {  	int cnt; /* increase in packets */  	unsigned int delta = 0; +	u32 snd_cwnd = tp->snd_cwnd; + +	if (unlikely(!snd_cwnd)) { +		pr_err_once("snd_cwnd is nul, please report this bug.\n"); +		snd_cwnd = 1U; +	}  	/* RFC3465: ABC Slow start  	 * Increase only after a full MSS of bytes is acked @@ -324,7 +330,7 @@ void tcp_slow_start(struct tcp_sock *tp)  	if (sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tcp_max_ssthresh)  		cnt = sysctl_tcp_max_ssthresh >> 1;	/* limited slow start */  	else -		cnt = tp->snd_cwnd;			/* exponential increase */ +		cnt = snd_cwnd;				/* exponential increase */  	/* RFC3465: ABC  	 * We MAY increase by 2 if discovered delayed ack @@ -334,11 +340,11 @@ void tcp_slow_start(struct tcp_sock *tp)  	tp->bytes_acked = 0;  	tp->snd_cwnd_cnt += cnt; -	while (tp->snd_cwnd_cnt >= tp->snd_cwnd) { -		tp->snd_cwnd_cnt -= tp->snd_cwnd; +	while (tp->snd_cwnd_cnt >= snd_cwnd) { +		tp->snd_cwnd_cnt -= snd_cwnd;  		delta++;  	} -	tp->snd_cwnd = min(tp->snd_cwnd + delta, tp->snd_cwnd_clamp); +	tp->snd_cwnd = min(snd_cwnd + delta, tp->snd_cwnd_clamp);  }  EXPORT_SYMBOL_GPL(tcp_slow_start);  |