From c117b25e0b7de2fd116f86dd6f105447dcc3d125 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 25 Jun 2015 10:07:21 +0100 Subject: [PATCH] [tcp] Do not shrink window when discarding received packets We currently shrink the TCP window permanently if we are ever forced (by a low-memory condition) to discard a previously received TCP packet. This behaviour was intended to reduce the number of retransmissions in a lossy network, since lost packets might potentially result in the entire window contents being retransmitted. Since commit e0fc8fe ("[tcp] Implement support for TCP Selective Acknowledgements (SACK)") the cost of lost packets has been reduced by around one order of magnitude, and the reduction in the window size (which affects the maximum throughput) is now the more significant cost. Remove the code which reduces the TCP maximum window size when a received packet is discarded. Reported-by: Wissam Shoukair Tested-by: Wissam Shoukair Signed-off-by: Michael Brown --- src/net/tcp.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/src/net/tcp.c b/src/net/tcp.c index aeacfd79..1a672dfa 100644 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -101,8 +101,6 @@ struct tcp_connection { * Equivalent to Rcv.Wind.Scale in RFC 1323 terminology */ uint8_t rcv_win_scale; - /** Maximum receive window */ - uint32_t max_rcv_win; /** Selective acknowledgement list (in host-endian order) */ struct tcp_sack_block sack[TCP_SACK_MAX]; @@ -291,7 +289,6 @@ static int tcp_open ( struct interface *xfer, struct sockaddr *peer, tcp->tcp_state = TCP_STATE_SENT ( TCP_SYN ); tcp_dump_state ( tcp ); tcp->snd_seq = random(); - tcp->max_rcv_win = TCP_MAX_WINDOW_SIZE; INIT_LIST_HEAD ( &tcp->tx_queue ); INIT_LIST_HEAD ( &tcp->rx_queue ); memcpy ( &tcp->peer, st_peer, sizeof ( tcp->peer ) ); @@ -615,7 +612,6 @@ static void tcp_xmit_sack ( struct tcp_connection *tcp, uint32_t sack_seq ) { size_t len = 0; size_t sack_len; uint32_t seq_len; - uint32_t app_win; uint32_t max_rcv_win; uint32_t max_representable_win; int rc; @@ -669,10 +665,9 @@ static void tcp_xmit_sack ( struct tcp_connection *tcp, uint32_t sack_seq ) { tcp_process_tx_queue ( tcp, len, iobuf, 0 ); /* Expand receive window if possible */ - max_rcv_win = tcp->max_rcv_win; - app_win = xfer_window ( &tcp->xfer ); - if ( max_rcv_win > app_win ) - max_rcv_win = app_win; + max_rcv_win = xfer_window ( &tcp->xfer ); + if ( max_rcv_win > TCP_MAX_WINDOW_SIZE ) + max_rcv_win = TCP_MAX_WINDOW_SIZE; max_representable_win = ( 0xffff << tcp->rcv_win_scale ); if ( max_rcv_win > max_representable_win ) max_rcv_win = max_representable_win; @@ -1482,24 +1477,12 @@ struct tcpip_protocol tcp_protocol __tcpip_protocol = { static unsigned int tcp_discard ( void ) { struct tcp_connection *tcp; struct io_buffer *iobuf; - struct tcp_rx_queued_header *tcpqhdr; - uint32_t max_win; unsigned int discarded = 0; /* Try to drop one queued RX packet from each connection */ list_for_each_entry ( tcp, &tcp_conns, list ) { list_for_each_entry_reverse ( iobuf, &tcp->rx_queue, list ) { - /* Limit window to prevent future discards */ - tcpqhdr = iobuf->data; - max_win = ( tcpqhdr->seq - tcp->rcv_ack ); - if ( max_win < tcp->max_rcv_win ) { - DBGC ( tcp, "TCP %p reducing maximum window " - "from %d to %d\n", - tcp, tcp->max_rcv_win, max_win ); - tcp->max_rcv_win = max_win; - } - /* Remove packet from queue */ list_del ( &iobuf->list ); free_iob ( iobuf );