> Author: mmacy
> Date: Tue May  8 02:22:34 2018
> New Revision: 333346
> URL: https://svnweb.freebsd.org/changeset/base/333346
> 
> Log:
>   Fix spurious retransmit recovery on low latency networks

Your commit message quality is defanitly much much better!!  Just one little 
nit...

>   
>   TCP's smoothed RTT (SRTT) can be much larger than an actual observed RTT. 
> This can be either because of hz restricting the calculable RTT to 10ms in 
> VMs or 1ms using the default 1000hz or simply because SRTT recently 
> incorporated a larger value.

Can you wrap lines at 80 characters please.
Thanks,

>   If an ACK arrives before the calculated badrxtwin (now + SRTT):
>   tp->t_badrxtwin = ticks + (tp->t_srtt >> (TCP_RTT_SHIFT + 1));
>   
>   We'll erroneously reset snd_una to snd_max. If multiple segments were 
> dropped and this happens repeatedly the transmit rate will be limited to 1MSS 
> per RTO until we've retransmitted all drops.
>   
>   Reported by:        rstone
>   Reviewed by:        hiren, transport
>   Approved by:        sbruno
>   MFC after:  1 month
>   Differential Revision:      https://reviews.freebsd.org/D8556
> 
> Modified:
>   head/sys/netinet/tcp_input.c
>   head/sys/netinet/tcp_output.c
>   head/sys/netinet/tcp_timer.c
> 
> Modified: head/sys/netinet/tcp_input.c
> ==============================================================================
> --- head/sys/netinet/tcp_input.c      Tue May  8 01:39:45 2018        
> (r333345)
> +++ head/sys/netinet/tcp_input.c      Tue May  8 02:22:34 2018        
> (r333346)
> @@ -1682,6 +1682,9 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru
>               to.to_tsecr -= tp->ts_offset;
>               if (TSTMP_GT(to.to_tsecr, tcp_ts_getticks()))
>                       to.to_tsecr = 0;
> +             else if (tp->t_flags & TF_PREVVALID &&
> +                      tp->t_badrxtwin != 0 && SEQ_LT(to.to_tsecr, 
> tp->t_badrxtwin))
> +                     cc_cong_signal(tp, th, CC_RTO_ERR);
>       }
>       /*
>        * Process options only when we get SYN/ACK back. The SYN case
> @@ -1794,9 +1797,10 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, stru
>                               TCPSTAT_INC(tcps_predack);
>  
>                               /*
> -                              * "bad retransmit" recovery.
> +                              * "bad retransmit" recovery without timestamps.
>                                */
> -                             if (tp->t_rxtshift == 1 &&
> +                             if ((to.to_flags & TOF_TS) == 0 &&
> +                                 tp->t_rxtshift == 1 &&
>                                   tp->t_flags & TF_PREVVALID &&
>                                   (int)(ticks - tp->t_badrxtwin) < 0) {
>                                       cc_cong_signal(tp, th, CC_RTO_ERR);
> @@ -2787,8 +2791,10 @@ process_ACK:
>                * original cwnd and ssthresh, and proceed to transmit where
>                * we left off.
>                */
> -             if (tp->t_rxtshift == 1 && tp->t_flags & TF_PREVVALID &&
> -                 (int)(ticks - tp->t_badrxtwin) < 0)
> +             if (tp->t_rxtshift == 1 &&
> +                 tp->t_flags & TF_PREVVALID &&
> +                 tp->t_badrxtwin &&
> +                 SEQ_LT(to.to_tsecr, tp->t_badrxtwin))
>                       cc_cong_signal(tp, th, CC_RTO_ERR);
>  
>               /*
> 
> Modified: head/sys/netinet/tcp_output.c
> ==============================================================================
> --- head/sys/netinet/tcp_output.c     Tue May  8 01:39:45 2018        
> (r333345)
> +++ head/sys/netinet/tcp_output.c     Tue May  8 02:22:34 2018        
> (r333346)
> @@ -206,7 +206,7 @@ tcp_output(struct tcpcb *tp)
>  #if defined(IPSEC) || defined(IPSEC_SUPPORT)
>       unsigned ipsec_optlen = 0;
>  #endif
> -     int idle, sendalot;
> +     int idle, sendalot, curticks;
>       int sack_rxmit, sack_bytes_rxmt;
>       struct sackhole *p;
>       int tso, mtu;
> @@ -808,9 +808,12 @@ send:
>               /* Timestamps. */
>               if ((tp->t_flags & TF_RCVD_TSTMP) ||
>                   ((flags & TH_SYN) && (tp->t_flags & TF_REQ_TSTMP))) {
> -                     to.to_tsval = tcp_ts_getticks() + tp->ts_offset;
> +                     curticks = tcp_ts_getticks();
> +                     to.to_tsval = curticks + tp->ts_offset;
>                       to.to_tsecr = tp->ts_recent;
>                       to.to_flags |= TOF_TS;
> +                     if (tp->t_rxtshift == 1)
> +                             tp->t_badrxtwin = curticks;
>               }
>  
>               /* Set receive buffer autosizing timestamp. */
> 
> Modified: head/sys/netinet/tcp_timer.c
> ==============================================================================
> --- head/sys/netinet/tcp_timer.c      Tue May  8 01:39:45 2018        
> (r333345)
> +++ head/sys/netinet/tcp_timer.c      Tue May  8 02:22:34 2018        
> (r333346)
> @@ -693,7 +693,12 @@ tcp_timer_rexmt(void * xtp)
>                       tp->t_flags |= TF_WASCRECOVERY;
>               else
>                       tp->t_flags &= ~TF_WASCRECOVERY;
> -             tp->t_badrxtwin = ticks + (tp->t_srtt >> (TCP_RTT_SHIFT + 1));
> +             if ((tp->t_flags & TF_RCVD_TSTMP) == 0)
> +                     tp->t_badrxtwin = ticks + (tp->t_srtt >> (TCP_RTT_SHIFT 
> + 1));
> +             /* In the event that we've negotiated timestamps
> +              * badrxtwin will be set to the value that we set
> +              * the retransmitted packet's to_tsval to by tcp_output
> +              */
>               tp->t_flags |= TF_PREVVALID;
>       } else
>               tp->t_flags &= ~TF_PREVVALID;
> 
> 

-- 
Rod Grimes                                                 rgri...@freebsd.org
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to