svn commit: r231421 - stable/8/sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Fri Feb 10 20:07:01 UTC 2012


Author: tuexen
Date: Fri Feb 10 20:07:01 2012
New Revision: 231421
URL: http://svn.freebsd.org/changeset/base/231421

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

Modified:
  stable/8/sys/netinet/sctp_structs.h
  stable/8/sys/netinet/sctp_sysctl.c
  stable/8/sys/netinet/sctputil.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)

Modified: stable/8/sys/netinet/sctp_structs.h
==============================================================================
--- stable/8/sys/netinet/sctp_structs.h	Fri Feb 10 20:00:21 2012	(r231420)
+++ stable/8/sys/netinet/sctp_structs.h	Fri Feb 10 20:07:01 2012	(r231421)
@@ -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: stable/8/sys/netinet/sctp_sysctl.c
==============================================================================
--- stable/8/sys/netinet/sctp_sysctl.c	Fri Feb 10 20:00:21 2012	(r231420)
+++ stable/8/sys/netinet/sctp_sysctl.c	Fri Feb 10 20:07:01 2012	(r231421)
@@ -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: stable/8/sys/netinet/sctputil.c
==============================================================================
--- stable/8/sys/netinet/sctputil.c	Fri Feb 10 20:00:21 2012	(r231420)
+++ stable/8/sys/netinet/sctputil.c	Fri Feb 10 20:07:01 2012	(r231421)
@@ -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)) {


More information about the svn-src-stable-8 mailing list