Exploring TCP throughput with DTrace

One key measure to use when assessing TCP throughput is assessing the amount of unacknowledged data in the pipe. In DTrace terms, the amount of unacknowledged data in bytes for the connection is the different between the next sequence number to send and the lowest unacknoweldged sequence number (tcps_snxt - tcps_suna). According to the theory, when the number of unacknowledged bytes for the connection is less than the receive window of the peer, the path bandwidth is the limiting factor for throughput. In other words, if we can fill the pipe without the peer TCP complaining (by virtue of its window size reaching 0), we are purely bandwidth-limited. If the peer's receive window is too small however, the sending TCP has to wait for acknowledgements before it can send more data. In this case the round-trip time (RTT) limits throughput. In such cases the effective throughput limit is the window size divided by the RTT, e.g. if the window size is 64K and the RTT is 0.5sec, the throughput is 128K/s.

So a neat way to visually determine if the receive window of clients may be too small should be to compare the distribution of unacknowledged byte values for the server versus the client's advertised receive window. If the unacked distribution overlaps the send window distribution such that it is to the right (or lower down in DTrace since quantizations are displayed vertically), it indicates that the amount of unacknowledged data regularly exceeds the client's receive window, so that it is possible that the sender may have more data to send but is blocked by a zero-window on the client side.

In the following example, we compare the distribution of unacked values to the receive window advertised by the receiver (10.175.96.92) for a large file download via http.

# dtrace -s tcp_tput.d
^C

  unacked(bytes)                                    10.175.96.92                                          80
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |                                         6        
               1 |                                         0        
               2 |                                         0        
               4 |                                         0        
               8 |                                         0        
              16 |                                         0        
              32 |                                         0        
              64 |                                         0        
             128 |                                         0        
             256 |                                         3        
             512 |                                         0        
            1024 |                                         0        
            2048 |                                         9        
            4096 |                                         14       
            8192 |                                         27       
           16384 |                                         67       
           32768 |@@                                       1464     
           65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   32396    
          131072 |                                         0        

  SWND(bytes)                                         10.175.96.92                                          80
           value  ------------- Distribution ------------- count    
           16384 |                                         0        
           32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 17067    
           65536 |                                         0        

Here we have a puzzle. We can see that the receiver's advertised window is in the 32768-65535 range, while the amount of unacknowledged data in the pipe is largely in the 65536-131071 range. What's going on here? Surely in a case like this we should see zero-window events, since the amount of data in the pipe regularly exceeds the window size of the receiver. We can see that we don't see any zero-window events since the SWND distribution displays no 0 values - it stays within the 32768-65535 range.

The explanation is straightforward enough. TCP Window scaling is in operation for this connection - the Window Scale TCP option is used on connection setup to allow a connection to advertise (and have advertised to it) a window greater than 65536 bytes. In this case the scaling shift is 1, so this explains why the SWND values are clustered in the 32768-65535 range rather than the 65536-131071 range - the SWND value needs to be multiplied by two since the reciever is also scaling its window by a shift factor of 1.

Here's the simple script that compares unacked and SWND distributions, fixed to take account of window scaling.

#!/usr/sbin/dtrace -s

#pragma D option quiet

tcp:::send
/ (args[4]->tcp_flags & (TH_SYN|TH_RST|TH_FIN)) == 0 /
{
        @unacked["unacked(bytes)", args[2]->ip_daddr, args[4]->tcp_sport] =
            quantize(args[3]->tcps_snxt - args[3]->tcps_suna);
}

tcp:::receive
/ (args[4]->tcp_flags & (TH_SYN|TH_RST|TH_FIN)) == 0 /
{
        @swnd["SWND(bytes)", args[2]->ip_saddr, args[4]->tcp_dport] =
            quantize((args[4]->tcp_window)*(1 << args[3]->tcps_snd_ws));

}

And here's the fixed output.

# dtrace -s tcp_tput_scaled.d
^C
  unacked(bytes)                                     10.175.96.92                                          80
           value  ------------- Distribution ------------- count    
              -1 |                                         0        
               0 |                                         39       
               1 |                                         0        
               2 |                                         0        
               4 |                                         0        
               8 |                                         0        
              16 |                                         0        
              32 |                                         0        
              64 |                                         0        
             128 |                                         0        
             256 |                                         3        
             512 |                                         0        
            1024 |                                         0        
            2048 |                                         4        
            4096 |                                         9        
            8192 |                                         22       
           16384 |                                         37       
           32768 |@                                        99       
           65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   3858     
          131072 |                                         0        

  SWND(bytes)                                         10.175.96.92                                          80
           value  ------------- Distribution ------------- count    
             512 |                                         0        
            1024 |                                         1        
            2048 |                                         0        
            4096 |                                         2        
            8192 |                                         4        
           16384 |                                         7        
           32768 |                                         14       
           65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  1956     
          131072 |                                         0        
Comments:

Post a Comment:
Comments are closed for this entry.
About

user12820842

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today