david/ipxe
Archived
1
0

[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 <wissams@mellanox.com>
Tested-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2015-06-25 10:07:21 +01:00
parent e46154fbb4
commit c117b25e0b

View File

@ -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 );