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
 	 * Equivalent to Rcv.Wind.Scale in RFC 1323 terminology
101
 	 * Equivalent to Rcv.Wind.Scale in RFC 1323 terminology
102
 	 */
102
 	 */
103
 	uint8_t rcv_win_scale;
103
 	uint8_t rcv_win_scale;
104
-	/** Maximum receive window */
105
-	uint32_t max_rcv_win;
106
 
104
 
107
 	/** Selective acknowledgement list (in host-endian order) */
105
 	/** Selective acknowledgement list (in host-endian order) */
108
 	struct tcp_sack_block sack[TCP_SACK_MAX];
106
 	struct tcp_sack_block sack[TCP_SACK_MAX];
291
 	tcp->tcp_state = TCP_STATE_SENT ( TCP_SYN );
289
 	tcp->tcp_state = TCP_STATE_SENT ( TCP_SYN );
292
 	tcp_dump_state ( tcp );
290
 	tcp_dump_state ( tcp );
293
 	tcp->snd_seq = random();
291
 	tcp->snd_seq = random();
294
-	tcp->max_rcv_win = TCP_MAX_WINDOW_SIZE;
295
 	INIT_LIST_HEAD ( &tcp->tx_queue );
292
 	INIT_LIST_HEAD ( &tcp->tx_queue );
296
 	INIT_LIST_HEAD ( &tcp->rx_queue );
293
 	INIT_LIST_HEAD ( &tcp->rx_queue );
297
 	memcpy ( &tcp->peer, st_peer, sizeof ( tcp->peer ) );
294
 	memcpy ( &tcp->peer, st_peer, sizeof ( tcp->peer ) );
615
 	size_t len = 0;
612
 	size_t len = 0;
616
 	size_t sack_len;
613
 	size_t sack_len;
617
 	uint32_t seq_len;
614
 	uint32_t seq_len;
618
-	uint32_t app_win;
619
 	uint32_t max_rcv_win;
615
 	uint32_t max_rcv_win;
620
 	uint32_t max_representable_win;
616
 	uint32_t max_representable_win;
621
 	int rc;
617
 	int rc;
669
 	tcp_process_tx_queue ( tcp, len, iobuf, 0 );
665
 	tcp_process_tx_queue ( tcp, len, iobuf, 0 );
670
 
666
 
671
 	/* Expand receive window if possible */
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
 	max_representable_win = ( 0xffff << tcp->rcv_win_scale );
671
 	max_representable_win = ( 0xffff << tcp->rcv_win_scale );
677
 	if ( max_rcv_win > max_representable_win )
672
 	if ( max_rcv_win > max_representable_win )
678
 		max_rcv_win = max_representable_win;
673
 		max_rcv_win = max_representable_win;
1482
 static unsigned int tcp_discard ( void ) {
1477
 static unsigned int tcp_discard ( void ) {
1483
 	struct tcp_connection *tcp;
1478
 	struct tcp_connection *tcp;
1484
 	struct io_buffer *iobuf;
1479
 	struct io_buffer *iobuf;
1485
-	struct tcp_rx_queued_header *tcpqhdr;
1486
-	uint32_t max_win;
1487
 	unsigned int discarded = 0;
1480
 	unsigned int discarded = 0;
1488
 
1481
 
1489
 	/* Try to drop one queued RX packet from each connection */
1482
 	/* Try to drop one queued RX packet from each connection */
1490
 	list_for_each_entry ( tcp, &tcp_conns, list ) {
1483
 	list_for_each_entry ( tcp, &tcp_conns, list ) {
1491
 		list_for_each_entry_reverse ( iobuf, &tcp->rx_queue, list ) {
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
 			/* Remove packet from queue */
1486
 			/* Remove packet from queue */
1504
 			list_del ( &iobuf->list );
1487
 			list_del ( &iobuf->list );
1505
 			free_iob ( iobuf );
1488
 			free_iob ( iobuf );

Loading…
Cancel
Save