aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/sysctl_net_ipv4.c8
-rw-r--r--net/ipv4/tcp_cong.c31
2 files changed, 30 insertions, 9 deletions
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 0aa304711a96..d68effe98e8d 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -803,6 +803,14 @@ ctl_table ipv4_table[] = {
803 .proc_handler = &proc_allowed_congestion_control, 803 .proc_handler = &proc_allowed_congestion_control,
804 .strategy = &strategy_allowed_congestion_control, 804 .strategy = &strategy_allowed_congestion_control,
805 }, 805 },
806 {
807 .ctl_name = NET_TCP_MAX_SSTHRESH,
808 .procname = "tcp_max_ssthresh",
809 .data = &sysctl_tcp_max_ssthresh,
810 .maxlen = sizeof(int),
811 .mode = 0644,
812 .proc_handler = &proc_dointvec,
813 },
806 { .ctl_name = 0 } 814 { .ctl_name = 0 }
807}; 815};
808 816
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
15int sysctl_tcp_max_ssthresh = 0;
16
15static DEFINE_SPINLOCK(tcp_cong_list_lock); 17static DEFINE_SPINLOCK(tcp_cong_list_lock);
16static LIST_HEAD(tcp_cong_list); 18static 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 */
279void tcp_slow_start(struct tcp_sock *tp) 282void 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}
301EXPORT_SYMBOL_GPL(tcp_slow_start); 314EXPORT_SYMBOL_GPL(tcp_slow_start);
302 315