Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 May 2007 14:02:33 -0400
From:      "Chris Harrer" <cjharrer@comcast.net>
To:        <freebsd-net@freebsd.org>
Subject:   RELENG 6.2 Slow Start Question
Message-ID:  <001001c7932d$6311f0c0$ac01020a@record>

next in thread | raw e-mail | index | archive | help
Hello All,

This is my first time posting a message to this list, so please excuse me if
this is not an appropriate message for this list (if it is inappropriate,
could you please direct me to a more appropriate place?).

I've been looking at some slow start code in the FreeBSD 6.2 RELENG, in
particular the following block that increments the CWND in Ack processing:

2128                 /*
2129                  * When new data is acked, open the congestion window.
2130                  * If the window gives us less than ssthresh packets
2131                  * in flight, open exponentially (maxseg per packet).
2132                  * Otherwise open linearly: maxseg per window
2133                  * (maxseg^2 / cwnd per packet).
2134                  */
2135                 if ((!tcp_do_newreno
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=tcp_do_newreno>;  && !tp
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=tp>; ->sack_enable) ||
2136                     !IN_FASTRECOVERY
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=IN_FASTRECOVERY>; (tp
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=tp>; )) {
2137                         register u_int
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=u_int>;  cw = tp
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=tp>; ->snd_cwnd;
2138                         register u_int
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=u_int>;  incr = tp
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=tp>; ->t_maxseg;
2139                         if (cw > tp
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=tp>; ->snd_ssthresh)
2140                                 incr = incr * incr / cw;
2141                         tp
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=tp>; ->snd_cwnd = min
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=min>; (cw+incr, TCP_MAXWIN
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=TCP_MAXWIN>; <<tp
<http://fxr.watson.org/fxr/ident?v=RELENG62;i=tp>; ->snd_scale);
2142                 }

Assume this connection is just opened, CWND has an initial value of 2920 and
snd_ssthresh is sufficiently big (for this example, use 17500). 

A write is given to TCP of length 8760 bytes.  Tcp_output determines it can
send the first 2920 bytes of that write based on snd_cwnd and does so.  A
single ACK is received that ACK's all 2920 bytes of data, in looking at the
code above, tp->snd_cwnd would get set to 4380 (assuming a t_maxseg of
1460).  This is in contrast to the description in Steven's Volume 1
regarding slow start increasing the window exponentially, as well as the
description in RFC 2581 whereby I would expect tp->snd_cwnd to be set to
5840.

After processing the ACK, tcp_output would send 3 new full segments as
opposed to 4 (i.e., all of the remaining data) which I would expect.

This seems obviously wrong to me, but it's code that always been there.  I'd
like to understand where my analysis goes wrong or why it's acceptable for
the call to tcp_output (after the acking of the first 2920 bytes of data) to
only send 3 packets as opposed to completing the transmission of the write
in two calls to tcp_output.

Thanks very much.

Chris



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?001001c7932d$6311f0c0$ac01020a>