diff options
author | John Heffner <jheffner@psc.edu> | 2007-03-25 22:21:45 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 01:23:19 -0400 |
commit | 886236c1247ab5e2ad9c73f6e9a652e3ae3c8b07 (patch) | |
tree | f0ab2d6f6b6c98c6042be100db752c2d492669ae /net/ipv4/tcp_cong.c | |
parent | 5ef814753eb810d900fbd77af7c87f6d04f0e551 (diff) |
[TCP]: Add RFC3742 Limited Slow-Start, controlled by variable sysctl_tcp_max_ssthresh.
Signed-off-by: John Heffner <jheffner@psc.edu>
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 | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 34ae3f13483a..ccd88407e0cd 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/list.h> | 12 | #include <linux/list.h> |
13 | #include <net/tcp.h> | 13 | #include <net/tcp.h> |
14 | 14 | ||
15 | int sysctl_tcp_max_ssthresh = 0; | ||
16 | |||
15 | static DEFINE_SPINLOCK(tcp_cong_list_lock); | 17 | static DEFINE_SPINLOCK(tcp_cong_list_lock); |
16 | static LIST_HEAD(tcp_cong_list); | 18 | static LIST_HEAD(tcp_cong_list); |
17 | 19 | ||
@@ -274,10 +276,13 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
274 | 276 | ||
275 | 277 | ||
276 | /* | 278 | /* |
277 | * Linear increase during slow start | 279 | * Slow start (exponential increase) with |
280 | * RFC3742 Limited Slow Start (fast linear increase) support. | ||
278 | */ | 281 | */ |
279 | void tcp_slow_start(struct tcp_sock *tp) | 282 | void tcp_slow_start(struct tcp_sock *tp) |
280 | { | 283 | { |
284 | int cnt = 0; | ||
285 | |||
281 | if (sysctl_tcp_abc) { | 286 | if (sysctl_tcp_abc) { |
282 | /* RFC3465: Slow Start | 287 | /* RFC3465: Slow Start |
283 | * TCP sender SHOULD increase cwnd by the number of | 288 | * TCP sender SHOULD increase cwnd by the number of |
@@ -286,17 +291,25 @@ void tcp_slow_start(struct tcp_sock *tp) | |||
286 | */ | 291 | */ |
287 | if (tp->bytes_acked < tp->mss_cache) | 292 | if (tp->bytes_acked < tp->mss_cache) |
288 | return; | 293 | return; |
289 | |||
290 | /* We MAY increase by 2 if discovered delayed ack */ | ||
291 | if (sysctl_tcp_abc > 1 && tp->bytes_acked >= 2*tp->mss_cache) { | ||
292 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) | ||
293 | tp->snd_cwnd++; | ||
294 | } | ||
295 | } | 294 | } |
295 | |||
296 | if (sysctl_tcp_max_ssthresh > 0 && | ||
297 | tp->snd_cwnd > sysctl_tcp_max_ssthresh) | ||
298 | cnt += sysctl_tcp_max_ssthresh>>1; | ||
299 | else | ||
300 | cnt += tp->snd_cwnd; | ||
301 | |||
302 | /* RFC3465: We MAY increase by 2 if discovered delayed ack */ | ||
303 | if (sysctl_tcp_abc > 1 && tp->bytes_acked >= 2*tp->mss_cache) | ||
304 | cnt <<= 1; | ||
296 | tp->bytes_acked = 0; | 305 | tp->bytes_acked = 0; |
297 | 306 | ||
298 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) | 307 | tp->snd_cwnd_cnt += cnt; |
299 | tp->snd_cwnd++; | 308 | while (tp->snd_cwnd_cnt >= tp->snd_cwnd) { |
309 | tp->snd_cwnd_cnt -= tp->snd_cwnd; | ||
310 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) | ||
311 | tp->snd_cwnd++; | ||
312 | } | ||
300 | } | 313 | } |
301 | EXPORT_SYMBOL_GPL(tcp_slow_start); | 314 | EXPORT_SYMBOL_GPL(tcp_slow_start); |
302 | 315 | ||