--- /dev/null
+From stable-bounces@linux.kernel.org Wed Mar 23 10:50:18 2005
+Date: Wed, 23 Mar 2005 10:48:24 -0800
+From: "David S. Miller" <davem@davemloft.net>
+To: stable@kernel.org
+Subject: [PATCH][TCP] 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>
+
+===== net/ipv4/tcp_input.c 1.92 vs edited =====
+--- 1.92/net/ipv4/tcp_input.c 2005-02-22 10:45:31 -08:00
++++ edited/net/ipv4/tcp_input.c 2005-03-23 10:55:18 -08:00
+@@ -1653,7 +1653,10 @@
+ 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;
+