aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorXiaoliang (David) Wei <davidwei79@gmail.com>2006-07-11 16:03:28 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-07-12 16:58:50 -0400
commit6150c22e2ac3f7dbe73e7ae7817785070d0cff1f (patch)
tree2506ea47e5ae101ab6f0df694480b1df46267b18 /net
parent781b456a980ec987a4be248f236c59658f651240 (diff)
[TCP] tcp_highspeed: Fix AI updates.
I think there is still a problem with the AIMD parameter update in HighSpeed TCP code. Line 125~138 of the code (net/ipv4/tcp_highspeed.c): /* Update AIMD parameters */ if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) { while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd && ca->ai < HSTCP_AIMD_MAX - 1) ca->ai++; } else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) { while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd && ca->ai > 0) ca->ai--; In fact, the second part (decreasing ca->ai) never decreases since the while loop's inequality is in the reverse direction. This leads to unfairness with multiple flows (once a flow happens to enjoy a higher ca->ai, it keeps enjoying that even its cwnd decreases) Here is a tentative fix (I also added a comment, trying to keep the change clear): Acked-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_highspeed.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c
index aaa1538c0692..fa3e1aad660c 100644
--- a/net/ipv4/tcp_highspeed.c
+++ b/net/ipv4/tcp_highspeed.c
@@ -139,14 +139,19 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
139 tp->snd_cwnd++; 139 tp->snd_cwnd++;
140 } 140 }
141 } else { 141 } else {
142 /* Update AIMD parameters */ 142 /* Update AIMD parameters.
143 *
144 * We want to guarantee that:
145 * hstcp_aimd_vals[ca->ai-1].cwnd <
146 * snd_cwnd <=
147 * hstcp_aimd_vals[ca->ai].cwnd
148 */
143 if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) { 149 if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
144 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd && 150 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
145 ca->ai < HSTCP_AIMD_MAX - 1) 151 ca->ai < HSTCP_AIMD_MAX - 1)
146 ca->ai++; 152 ca->ai++;
147 } else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) { 153 } else if (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd) {
148 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd && 154 while (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd)
149 ca->ai > 0)
150 ca->ai--; 155 ca->ai--;
151 } 156 }
152 157