Browse Source

[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>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
c117b25e0b
1 changed files with 3 additions and 20 deletions
  1. 3
    20
      src/net/tcp.c

+ 3
- 20
src/net/tcp.c View File

@@ -101,8 +101,6 @@ struct tcp_connection {
101 101
 	 * Equivalent to Rcv.Wind.Scale in RFC 1323 terminology
102 102
 	 */
103 103
 	uint8_t rcv_win_scale;
104
-	/** Maximum receive window */
105
-	uint32_t max_rcv_win;
106 104
 
107 105
 	/** Selective acknowledgement list (in host-endian order) */
108 106
 	struct tcp_sack_block sack[TCP_SACK_MAX];
@@ -291,7 +289,6 @@ static int tcp_open ( struct interface *xfer, struct sockaddr *peer,
291 289
 	tcp->tcp_state = TCP_STATE_SENT ( TCP_SYN );
292 290
 	tcp_dump_state ( tcp );
293 291
 	tcp->snd_seq = random();
294
-	tcp->max_rcv_win = TCP_MAX_WINDOW_SIZE;
295 292
 	INIT_LIST_HEAD ( &tcp->tx_queue );
296 293
 	INIT_LIST_HEAD ( &tcp->rx_queue );
297 294
 	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 ) {
615 612
 	size_t len = 0;
616 613
 	size_t sack_len;
617 614
 	uint32_t seq_len;
618
-	uint32_t app_win;
619 615
 	uint32_t max_rcv_win;
620 616
 	uint32_t max_representable_win;
621 617
 	int rc;
@@ -669,10 +665,9 @@ static void tcp_xmit_sack ( struct tcp_connection *tcp, uint32_t sack_seq ) {
669 665
 	tcp_process_tx_queue ( tcp, len, iobuf, 0 );
670 666
 
671 667
 	/* Expand receive window if possible */
672
-	max_rcv_win = tcp->max_rcv_win;
673
-	app_win = xfer_window ( &tcp->xfer );
674
-	if ( max_rcv_win > app_win )
675
-		max_rcv_win = app_win;
668
+	max_rcv_win = xfer_window ( &tcp->xfer );
669
+	if ( max_rcv_win > TCP_MAX_WINDOW_SIZE )
670
+		max_rcv_win = TCP_MAX_WINDOW_SIZE;
676 671
 	max_representable_win = ( 0xffff << tcp->rcv_win_scale );
677 672
 	if ( max_rcv_win > max_representable_win )
678 673
 		max_rcv_win = max_representable_win;
@@ -1482,24 +1477,12 @@ struct tcpip_protocol tcp_protocol __tcpip_protocol = {
1482 1477
 static unsigned int tcp_discard ( void ) {
1483 1478
 	struct tcp_connection *tcp;
1484 1479
 	struct io_buffer *iobuf;
1485
-	struct tcp_rx_queued_header *tcpqhdr;
1486
-	uint32_t max_win;
1487 1480
 	unsigned int discarded = 0;
1488 1481
 
1489 1482
 	/* Try to drop one queued RX packet from each connection */
1490 1483
 	list_for_each_entry ( tcp, &tcp_conns, list ) {
1491 1484
 		list_for_each_entry_reverse ( iobuf, &tcp->rx_queue, list ) {
1492 1485
 
1493
-			/* Limit window to prevent future discards */
1494
-			tcpqhdr = iobuf->data;
1495
-			max_win = ( tcpqhdr->seq - tcp->rcv_ack );
1496
-			if ( max_win < tcp->max_rcv_win ) {
1497
-				DBGC ( tcp, "TCP %p reducing maximum window "
1498
-				       "from %d to %d\n",
1499
-				       tcp, tcp->max_rcv_win, max_win );
1500
-				tcp->max_rcv_win = max_win;
1501
-			}
1502
-
1503 1486
 			/* Remove packet from queue */
1504 1487
 			list_del ( &iobuf->list );
1505 1488
 			free_iob ( iobuf );

Loading…
Cancel
Save