svn commit: r193941 - head/sys/netinet

Bruce Evans brde at optusnet.com.au
Tue Jun 16 00:04:48 UTC 2009


On Mon, 15 Jun 2009, John Baldwin wrote:

> On Friday 12 June 2009 8:56:56 pm Bruce Evans wrote:
>> On Fri, 12 Jun 2009, John Baldwin wrote:
> ...
>>> FWIW, the variables were signed before they were changed to unsigned and are now
>>> back as signed again.  It just seems really odd to have the types not match
>>> 'ticks' especially since many of the values are just cached copies of 'ticks'.
>>
>> No, they were originally u_long and stayed that way until you changed them
>> (except possibly for newer variables).  The type of `ticks' is just wrong,
>> and fixing that would take more work, but there is no reason to propagate
>> this bug to new variables.  The original version is:
>
> Gah, I had misremembered the diffs, they were indeed unsigned.  Here is my
> attempt at trying to fix things then based on my understanding so far:

This is about what I want.

> - It changes the variables back to unsigned (but u_int instead of unsigned
>  long).  It also changes a few other members to be u_int instead of int such
>  as the two rtttime members.
> - I changed t_starttime in the timewait structure to u_int.
> - I changed t_recent in the timewait structure to u_int32_t as it is only
>  used in relation to other u_int32_t variables.
> - I also attempted to fix overflow errors with t_badrxtwin by using
>  subtraction and casting the result to an int to compare with zero instead
>  of doing a direct comparison.
> - I cast 'ticks' to u_int in the code to compute a new isn.  I'm not sure if
>  this is needed.

This shouldn't be needed.  The operands of any binary operation are
promoted to a common type, and that type should be u_int since one of
the operands should have type u_int even if `ticks' doesn't.  It only
makes sense to cast things both operands are cast in all binary
operations where there _might_ , but that would be ugly and too careful.
The types should be required to be not _too_ dissimilar (no mixing of
ints with u_longs, and no opaque types so that we cannot tell if the
types are dissimilar) so that the default promotions work right.

> - Some style fixes to remove extra ()'s from 'ticks - t_rcvtime'.
>
> --- //depot/projects/smpng/sys/netinet/tcp_input.c	2009/06/12 13:45:50
> +++ //depot/user/jhb/socket/netinet/tcp_input.c	2009/06/15 17:22:13
> @@ -1296,7 +1296,7 @@
> 				 * "bad retransmit" recovery.
> 				 */
> 				if (tp->t_rxtshift == 1 &&
> -				    ticks < tp->t_badrxtwin) {
> +				    (int)(ticks - tp->t_badrxtwin) < 0) {
> 					TCPSTAT_INC(tcps_sndrexmitbad);
> 					tp->snd_cwnd = tp->snd_cwnd_prev;
> 					tp->snd_ssthresh =

This seems to be best for handling t_badrxtwin.

I note that you don't cast `ticks' here or in most places.

> --- //depot/projects/smpng/sys/netinet/tcp_timer.c	2009/04/14 19:06:19
> +++ //depot/user/jhb/socket/netinet/tcp_timer.c	2009/06/15 17:22:13
> @@ -418,8 +418,8 @@
> 	 * backoff that we would use if retransmitting.
> 	 */
> 	if (tp->t_rxtshift == TCP_MAXRXTSHIFT &&
> -	    ((ticks - tp->t_rcvtime) >= tcp_maxpersistidle ||
> -	     (ticks - tp->t_rcvtime) >= TCP_REXMTVAL(tp) * tcp_totbackoff)) {
> +	    (ticks - tp->t_rcvtime >= tcp_maxpersistidle ||
> +	     ticks - tp->t_rcvtime >= TCP_REXMTVAL(tp) * tcp_totbackoff)) {
> 		TCPSTAT_INC(tcps_persistdrop);
> 		tp = tcp_drop(tp, ETIMEDOUT);
> 		goto out;

Do we want to keep the non-KNF indentation (1 char extra to line things up)?

> --- //depot/projects/smpng/sys/netinet/tcp_timewait.c	2009/06/09 15:15:22
> +++ //depot/user/jhb/socket/netinet/tcp_timewait.c	2009/06/15 17:22:13
> @@ -322,8 +322,10 @@
> 	tcp_seq new_irs = tw->irs;
>
> 	INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
> -	new_iss += (ticks - tw->t_starttime) * (ISN_BYTES_PER_SECOND / hz);
> -	new_irs += (ticks - tw->t_starttime) * (MS_ISN_BYTES_PER_SECOND / hz);
> +	new_iss += ((u_int)ticks - tw->t_starttime) *
> +	    (ISN_BYTES_PER_SECOND / hz);
> +	new_irs += ((u_int)ticks - tw->t_starttime) *
> +	    (MS_ISN_BYTES_PER_SECOND / hz);

This t_starttime (should be tw_starttime) is now u_int (was u_long), so
you don't need the cast here -- the cast has no effect.  When t_starttime
was u_long, the safest cast would have been of t_starttime down to u_int.

> --- //depot/projects/smpng/sys/netinet/tcp_var.h	2009/06/12 13:45:50
> +++ //depot/user/jhb/socket/netinet/tcp_var.h	2009/06/15 17:22:13
> @@ -139,12 +139,12 @@
>
> 	u_int	t_maxopd;		/* mss plus options */
>
> -	int	t_rcvtime;		/* inactivity time */
> -	int	t_starttime;		/* time connection was established */
> -	int	t_rtttime;		/* round trip time */
> +	u_int	t_rcvtime;		/* inactivity time */
> +	u_int	t_starttime;		/* time connection was established */
> +	u_int	t_rtttime;		/* round trip time */

I would prefer the delta-times (like t_rtttime) to remain as ints.  Having
everything of the same type is safer, and having everything of signed
type allows better overflow checking (gcc -ftrapv (*)).  Whether ints are
actually safer for r_tttime depend on how it is used.  Oops, I misread
t_rtttime as being the rtt and a delta-time.  It seems to be actually
an absolute time for the start of rtt measurement.  Its comment is thus
now just wrong.

(*) I bet kernels compiled with -ftrapv don't boot.  They need a little
from libgcc to compile.  I haven't actually tried compiling them.
-ftrapv is only documented to trap for overflow on "+-*" binary
operations.  I can't find anything like it to trap for overflow on
other operations (other binary operations starting with division,
,assignment, conversions due to prototypes).  gcc -trapv still generates
large slow code with libcalls for "+-*" and doesn't generate the much
smaller but possibly slower i386 "into" trap.  ISTR that "into" only
works for very basic operations too.

Bruce


More information about the svn-src-all mailing list