• David Howells's avatar
    rxrpc: Fix loss of RTT samples due to interposed ACK · 4700c4d8
    David Howells authored
    The Rx protocol has a mechanism to help generate RTT samples that works by
    a client transmitting a REQUESTED-type ACK when it receives a DATA packet
    that has the REQUEST_ACK flag set.
    
    The peer, however, may interpose other ACKs before transmitting the
    REQUESTED-ACK, as can be seen in the following trace excerpt:
    
     rxrpc_tx_data: c=00000044 DATA d0b5ece8:00000001 00000001 q=00000001 fl=07
     rxrpc_rx_ack: c=00000044 00000001 PNG r=00000000 f=00000002 p=00000000 n=0
     rxrpc_rx_ack: c=00000044 00000002 REQ r=00000001 f=00000002 p=00000001 n=0
     ...
    
    DATA packet 1 (q=xx) has REQUEST_ACK set (bit 1 of fl=xx).  The incoming
    ping (labelled PNG) hard-acks the request DATA packet (f=xx exceeds the
    sequence number of the DATA packet), causing it to be discarded from the Tx
    ring.  The ACK that was requested (labelled REQ, r=xx references the serial
    of the DATA packet) comes after the ping, but the sk_buff holding the
    timestamp has gone and the RTT sample is lost.
    
    This is particularly noticeable on RPC calls used to probe the service
    offered by the peer.  A lot of peers end up with an unknown RTT because we
    only ever sent a single RPC.  This confuses the server rotation algorithm.
    
    Fix this by caching the information about the outgoing packet in RTT
    calculations in the rxrpc_call struct rather than looking in the Tx ring.
    
    A four-deep buffer is maintained and both REQUEST_ACK-flagged DATA and
    PING-ACK transmissions are recorded in there.  When the appropriate
    response ACK is received, the buffer is checked for a match and, if found,
    an RTT sample is recorded.
    
    If a received ACK refers to a packet with a later serial number than an
    entry in the cache, that entry is presumed lost and the entry is made
    available to record a new transmission.
    
    ACKs types other than REQUESTED-type and PING-type cause any matching
    sample to be cancelled as they don't necessarily represent a useful
    measurement.
    
    If there's no space in the buffer on ping/data transmission, the sample
    base is discarded.
    
    Fixes: 50235c4b ("rxrpc: Obtain RTT data by requesting ACKs on DATA packets")
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    4700c4d8
output.c 17.5 KB