summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavem@davemloft.net <davem@davemloft.net>2005-04-07 11:45:12 -0700
committerGreg KH <gregkh@suse.de>2005-05-12 10:00:20 -0700
commita4e879009d8be23efd79e4f18fcdbcfa9fcc83e1 (patch)
treea0a1df928ad95e911cc54d08b93ed409870b6ead
parentc05aa51378f0b9fe1ce0d65b6c6b886dd32dd383 (diff)
downloadlinux-stable-a4e879009d8be23efd79e4f18fcdbcfa9fcc83e1.tar.gz
linux-stable-a4e879009d8be23efd79e4f18fcdbcfa9fcc83e1.tar.bz2
linux-stable-a4e879009d8be23efd79e4f18fcdbcfa9fcc83e1.zip
[PATCH] Fix BIC congestion avoidance algorithm error
Since BIC is the default congestion control algorithm enabled in every 2.6.x kernel out there, fixing errors in it becomes quite critical. A flaw in the loss handling caused it to not perform the binary search regimen of the BIC algorithm properly. The fix below from Stephen Hemminger has been heavily verified. [TCP]: BIC not binary searching correctly While redoing BIC for the split up version, I discovered that the existing 2.6.11 code doesn't really do binary search. It ends up being just a slightly modified version of Reno. See attached graphs to see the effect over simulated 1mbit environment. The problem is that BIC is supposed to reset the cwnd to the last loss value rather than ssthresh when loss is detected. The correct code (from the BIC TCP code for Web100) is in this patch. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Chris Wright <chrisw@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--net/ipv4/tcp_input.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 8a71e824e17e..4819cb60c5a4 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1653,7 +1653,10 @@ static void DBGUNDO(struct sock *sk, struct tcp_sock *tp, const char *msg)
static void tcp_undo_cwr(struct tcp_sock *tp, int undo)
{
if (tp->prior_ssthresh) {
- tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1);
+ if (tcp_is_bic(tp))
+ tp->snd_cwnd = max(tp->snd_cwnd, tp->bictcp.last_max_cwnd);
+ else
+ tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1);
if (undo && tp->prior_ssthresh > tp->snd_ssthresh) {
tp->snd_ssthresh = tp->prior_ssthresh;