tcp: do not slow start when cwnd equals ssthresh
authorYuchung Cheng <ycheng@google.com>
Thu, 9 Jul 2015 20:16:30 +0000 (13:16 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 9 Jul 2015 21:22:52 +0000 (14:22 -0700)
In the original design slow start is only used to raise cwnd
when cwnd is stricly below ssthresh. It makes little sense
to slow start when cwnd == ssthresh: especially
when hystart has set ssthresh in the initial ramp, or after
recovery when cwnd resets to ssthresh. Not doing so will
also help reduce the buffer bloat slightly.

Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Nandita Dukkipati <nanditad@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/tcp.h
net/ipv4/tcp_cdg.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_hybla.c

index dba22fc1b065a70b9604872b1460c7b2ea24db1d..364426a2be5a0f7f0a2e6daaf6ce9b9a2f3e3304 100644 (file)
@@ -991,7 +991,7 @@ static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
 
 static inline bool tcp_in_slow_start(const struct tcp_sock *tp)
 {
-       return tp->snd_cwnd <= tp->snd_ssthresh;
+       return tp->snd_cwnd < tp->snd_ssthresh;
 }
 
 static inline bool tcp_in_initial_slowstart(const struct tcp_sock *tp)
index 8c6fd3d5e40feeb3c0b422d0e697e1a674b4f576..167b6a3e1b9868c88e5553b114556ae312dfb99f 100644 (file)
@@ -264,7 +264,7 @@ static void tcp_cdg_cong_avoid(struct sock *sk, u32 ack, u32 acked)
        u32 prior_snd_cwnd;
        u32 incr;
 
-       if (tp->snd_cwnd < tp->snd_ssthresh && hystart_detect)
+       if (tcp_in_slow_start(tp) && hystart_detect)
                tcp_cdg_hystart_update(sk);
 
        if (after(ack, ca->rtt_seq) && ca->rtt.v64) {
index 654729a8cb23f724cca59130580dd6a1ab6a8416..a2ed23c595cf185cadbebcdf19e801012a64250a 100644 (file)
@@ -365,10 +365,8 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
  */
 u32 tcp_slow_start(struct tcp_sock *tp, u32 acked)
 {
-       u32 cwnd = tp->snd_cwnd + acked;
+       u32 cwnd = min(tp->snd_cwnd + acked, tp->snd_ssthresh);
 
-       if (cwnd > tp->snd_ssthresh)
-               cwnd = tp->snd_ssthresh + 1;
        acked -= cwnd - tp->snd_cwnd;
        tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp);
 
index f963b274f2b0436755ebe8bb5586b1ec9682c336..083831e359df92ca9ba0fe7dd5a7a76fe41a94b0 100644 (file)
@@ -112,7 +112,7 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 
        rho_fractions = ca->rho_3ls - (ca->rho << 3);
 
-       if (tp->snd_cwnd < tp->snd_ssthresh) {
+       if (tcp_in_slow_start(tp)) {
                /*
                 * slow start
                 *      INC = 2^RHO - 1