Author: tuexen
Date: Thu Feb 24 22:36:40 2011
New Revision: 219013
URL: http://svn.freebsd.org/changeset/base/219013

Log:
  * Cleanup the code computing the retransmission timeout.
  * Fix an initialization bug for the scaled variance of the RTO.
  
  MFC after: 3 months.

Modified:
  head/sys/netinet/sctp_structs.h
  head/sys/netinet/sctp_sysctl.c
  head/sys/netinet/sctputil.c

Modified: head/sys/netinet/sctp_structs.h
==============================================================================
--- head/sys/netinet/sctp_structs.h     Thu Feb 24 22:11:36 2011        
(r219012)
+++ head/sys/netinet/sctp_structs.h     Thu Feb 24 22:36:40 2011        
(r219013)
@@ -245,7 +245,7 @@ struct sctp_nets {
        /* smoothed average things for RTT and RTO itself */
        int lastsa;
        int lastsv;
-       int rtt;                /* last measured rtt value in ms */
+       uint64_t rtt;           /* last measured rtt value in us */
        unsigned int RTO;
 
        /* This is used for SHUTDOWN/SHUTDOWN-ACK/SEND or INIT timers */
@@ -254,6 +254,10 @@ struct sctp_nets {
 
        /* last time in seconds I sent to it */
        struct timeval last_sent_time;
+
+       /* JRS - struct used in HTCP algorithm */
+       struct htcp htcp_ca;
+
        int ref_count;
 
        /* Congestion stats per destination */
@@ -267,7 +271,6 @@ struct sctp_nets {
        uint32_t ecn_prev_cwnd; /* ECN prev cwnd at first ecn_echo seen in new
                                 * window */
        uint32_t partial_bytes_acked;   /* in CA tracks when to incr a MTU */
-       uint32_t prev_rtt;
        /* tracking variables to avoid the aloc/free in sack processing */
        unsigned int net_ack;
        unsigned int net_ack2;
@@ -298,7 +301,6 @@ struct sctp_nets {
        uint32_t tos_flowlabel;
 
        struct timeval start_time;      /* time when this net was created */
-       struct timeval last_measured_rtt;
        uint32_t marked_retrans;/* number or DATA chunks marked for timer
                                 * based retransmissions */
        uint32_t marked_fastretrans;
@@ -348,8 +350,6 @@ struct sctp_nets {
        uint8_t RTO_measured;   /* Have we done the first measure */
        uint8_t last_hs_used;   /* index into the last HS table entry we used */
        uint8_t lan_type;
-       /* JRS - struct used in HTCP algorithm */
-       struct htcp htcp_ca;
        uint32_t flowid;
 #ifdef INVARIANTS
        uint8_t flowidset;

Modified: head/sys/netinet/sctp_sysctl.c
==============================================================================
--- head/sys/netinet/sctp_sysctl.c      Thu Feb 24 22:11:36 2011        
(r219012)
+++ head/sys/netinet/sctp_sysctl.c      Thu Feb 24 22:36:40 2011        
(r219013)
@@ -477,7 +477,7 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
                                xraddr.cwnd = net->cwnd;
                                xraddr.flight_size = net->flight_size;
                                xraddr.mtu = net->mtu;
-                               xraddr.rtt = net->rtt;
+                               xraddr.rtt = net->rtt / 1000;
                                xraddr.start_time.tv_sec = (uint32_t) 
net->start_time.tv_sec;
                                xraddr.start_time.tv_usec = (uint32_t) 
net->start_time.tv_usec;
                                SCTP_INP_RUNLOCK(inp);

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c Thu Feb 24 22:11:36 2011        (r219012)
+++ head/sys/netinet/sctputil.c Thu Feb 24 22:36:40 2011        (r219013)
@@ -113,7 +113,7 @@ rto_logging(struct sctp_nets *net, int f
 
        memset(&sctp_clog, 0, sizeof(sctp_clog));
        sctp_clog.x.rto.net = (void *)net;
-       sctp_clog.x.rto.rtt = net->prev_rtt;
+       sctp_clog.x.rto.rtt = net->rtt / 1000;
        SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
            SCTP_LOG_EVENT_RTT,
            from,
@@ -2475,9 +2475,8 @@ sctp_calculate_rto(struct sctp_tcb *stcb
         * given an association and the starting time of the current RTT
         * period (in value1/value2) return RTO in number of msecs.
         */
-       int calc_time = 0;
-       int o_calctime;
-       uint32_t new_rto = 0;
+       int32_t rtt;            /* RTT in ms */
+       uint32_t new_rto;
        int first_measure = 0;
        struct timeval now, then, *old;
 
@@ -2497,95 +2496,58 @@ sctp_calculate_rto(struct sctp_tcb *stcb
        /************************/
        /* get the current time */
        (void)SCTP_GETTIME_TIMEVAL(&now);
-       /*
-        * Record the real time of the last RTT for use in DC-CC.
-        */
-       net->last_measured_rtt = now;
-       timevalsub(&net->last_measured_rtt, old);
+       timevalsub(&now, old);
+       /* store the current RTT in us */
+       net->rtt = (uint64_t) 10000000 *(uint64_t) now.tv_sec +
+                (uint64_t) now.tv_usec;
+
+       /* computer rtt in ms */
+       rtt = net->rtt / 1000;
 
        /* Do we need to determine the lan type? */
-       if ((local_lan_determine == SCTP_DETERMINE_LL_OK) && (net->lan_type == 
SCTP_LAN_UNKNOWN)) {
-               if ((net->last_measured_rtt.tv_sec) ||
-                   (net->last_measured_rtt.tv_usec > SCTP_LOCAL_LAN_RTT)) {
+       if ((local_lan_determine == SCTP_DETERMINE_LL_OK) &&
+           (net->lan_type == SCTP_LAN_UNKNOWN)) {
+               if (net->rtt > SCTP_LOCAL_LAN_RTT) {
                        net->lan_type = SCTP_LAN_INTERNET;
                } else {
                        net->lan_type = SCTP_LAN_LOCAL;
                }
        }
-       /* compute the RTT value */
-       if ((u_long)now.tv_sec > (u_long)old->tv_sec) {
-               calc_time = ((u_long)now.tv_sec - (u_long)old->tv_sec) * 1000;
-               if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
-                       calc_time += (((u_long)now.tv_usec -
-                           (u_long)old->tv_usec) / 1000);
-               } else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
-                       /* Borrow 1,000ms from current calculation */
-                       calc_time -= 1000;
-                       /* Add in the slop over */
-                       calc_time += ((int)now.tv_usec / 1000);
-                       /* Add in the pre-second ms's */
-                       calc_time += (((int)1000000 - (int)old->tv_usec) / 
1000);
-               }
-       } else if ((u_long)now.tv_sec == (u_long)old->tv_sec) {
-               if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
-                       calc_time = ((u_long)now.tv_usec -
-                           (u_long)old->tv_usec) / 1000;
-               } else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
-                       /* impossible .. garbage in nothing out */
-                       goto calc_rto;
-               } else if ((u_long)now.tv_usec == (u_long)old->tv_usec) {
-                       /*
-                        * We have to have 1 usec :-D this must be the
-                        * loopback.
-                        */
-                       calc_time = 1;
-               } else {
-                       /* impossible .. garbage in nothing out */
-                       goto calc_rto;
-               }
-       } else {
-               /* Clock wrapped? */
-               goto calc_rto;
-       }
        /***************************/
        /* 2. update RTTVAR & SRTT */
        /***************************/
-       net->rtt = o_calctime = calc_time;
-       /* this is Van Jacobson's integer version */
+       /*-
+        * Compute the scaled average lastsa and the
+        * scaled variance lastsv as described in van Jacobson
+        * Paper "Congestion Avoidance and Control", Annex A.
+        *
+        * (net->lastsa >> SCTP_RTT_SHIFT) is the srtt
+        * (net->lastsa >> SCTP_RTT_VAR_SHIFT) is the rttvar
+        */
        if (net->RTO_measured) {
-               calc_time -= (net->lastsa >> SCTP_RTT_SHIFT);   /* take away 
1/8th when
-                                                                * shift=3 */
+               rtt -= (net->lastsa >> SCTP_RTT_SHIFT);
+               net->lastsa += rtt;
+               if (rtt < 0) {
+                       rtt = -rtt;
+               }
+               rtt -= (net->lastsv >> SCTP_RTT_VAR_SHIFT);
+               net->lastsv += rtt;
                if (SCTP_BASE_SYSCTL(sctp_logging_level) & 
SCTP_RTTVAR_LOGGING_ENABLE) {
                        rto_logging(net, SCTP_LOG_RTTVAR);
                }
-               net->prev_rtt = o_calctime;
-               net->lastsa += calc_time;       /* add 7/8th into sa when
-                                                * shift=3 */
-               if (calc_time < 0) {
-                       calc_time = -calc_time;
-               }
-               calc_time -= (net->lastsv >> SCTP_RTT_VAR_SHIFT);       /* take 
away 1/4 when
-                                                                        * VAR 
shift=2 */
-               net->lastsv += calc_time;
-               if (net->lastsv == 0) {
-                       net->lastsv = SCTP_CLOCK_GRANULARITY;
-               }
        } else {
                /* First RTO measurment */
                net->RTO_measured = 1;
-               net->lastsa = calc_time << SCTP_RTT_SHIFT;      /* Multiply by 
8 when
-                                                                * shift=3 */
-               net->lastsv = calc_time;
-               if (net->lastsv == 0) {
-                       net->lastsv = SCTP_CLOCK_GRANULARITY;
-               }
                first_measure = 1;
-               net->prev_rtt = o_calctime;
+               net->lastsa = rtt << SCTP_RTT_SHIFT;
+               net->lastsv = (rtt / 2) << SCTP_RTT_VAR_SHIFT;
                if (SCTP_BASE_SYSCTL(sctp_logging_level) & 
SCTP_RTTVAR_LOGGING_ENABLE) {
                        rto_logging(net, SCTP_LOG_INITIAL_RTT);
                }
        }
-calc_rto:
+       if (net->lastsv == 0) {
+               net->lastsv = SCTP_CLOCK_GRANULARITY;
+       }
        new_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv;
        if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
            (stcb->asoc.sat_network_lockout == 0)) {
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to