• David Howells's avatar
    rxrpc: Pass the last Tx packet marker in the annotation buffer · 70790dbe
    David Howells authored
    When the last packet of data to be transmitted on a call is queued, tx_top
    is set and then the RXRPC_CALL_TX_LAST flag is set.  Unfortunately, this
    leaves a race in the ACK processing side of things because the flag affects
    the interpretation of tx_top and also allows us to start receiving reply
    data before we've finished transmitting.
    
    To fix this, make the following changes:
    
     (1) rxrpc_queue_packet() now sets a marker in the annotation buffer
         instead of setting the RXRPC_CALL_TX_LAST flag.
    
     (2) rxrpc_rotate_tx_window() detects the marker and sets the flag in the
         same context as the routines that use it.
    
     (3) rxrpc_end_tx_phase() is simplified to just shift the call state.
         The Tx window must have been rotated before calling to discard the
         last packet.
    
     (4) rxrpc_receiving_reply() is added to handle the arrival of the first
         DATA packet of a reply to a client call (which is an implicit ACK of
         the Tx phase).
    
     (5) The last part of rxrpc_input_ack() is reordered to perform Tx
         rotation, then soft-ACK application and then to end the phase if we've
         rotated the last packet.  In the event of a terminal ACK, the soft-ACK
         application will be skipped as nAcks should be 0.
    
     (6) rxrpc_input_ackall() now has to rotate as well as ending the phase.
    
    In addition:
    
     (7) Alter the transmit tracepoint to log the rotation of the last packet.
    
     (8) Remove the no-longer relevant queue_reqack tracepoint note.  The
         ACK-REQUESTED packet header flag is now set as needed when we actually
         transmit the packet and may vary by retransmission.
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    70790dbe
sendmsg.c 14.9 KB