Re: delayed ACKs for retransmitted packets: ouch! (fwd)

Neal Cardwell (cardwell@cs.washington.edu)
Sat, 7 Nov 1998 14:19:25 -0800 (PST)

Wow. Leave it to the head honcho Linux TCP hacker to stay up all night on
a Friday night to fix something!

---------- Forwarded message ----------
Date: Sat, 7 Nov 1998 06:55:48 -0800
From: David S. Miller <davem@dm.cobaltmicro.com>
To: cardwell@cs.washington.edu
Cc: tcp-impl@cthulhu.engr.sgi.com
Subject: Re: delayed ACKs for retransmitted packets: ouch!

Date: Mon, 2 Nov 1998 19:19:40 -0800 (PST)
From: Neal Cardwell <cardwell@cs.washington.edu>

during this period I'm getting about 30Kbps on average, and not so
happy about the $ i forked over for DSL buying me modem
performance!

Sorry I did not respond sooner.

Pick your poison, here is the fix for both 2.0.x and 2.1.x
Linux TCP stacks. First 2.0.x:

--- net/ipv4/tcp_input.c.~1~ Tue Jul 21 08:13:48 1998
+++ net/ipv4/tcp_input.c Sat Nov 7 06:48:59 1998
@@ -1929,8 +1929,14 @@
* Delay the ack if possible. Send ack's to
* fin frames immediately as there shouldn't be
* anything more to come.
+ *
+ * ACK immediately if we still have any out of
+ * order data. This is because we desire "maximum
+ * feedback during loss". --DaveM
*/
- if (!sk->delay_acks || th->fin) {
+ if (!sk->delay_acks || th->fin ||
+ ((sk->acked_seq == skb->end_seq) &&
+ (skb->next != (struct sk_buff *) &sk->receive_queue))) {
tcp_send_ack(sk);
} else {
/*

And here is the same fix for current 2.1.x Linux TCP:

Index: net/ipv4/tcp_input.c
===================================================================
RCS file: /vger/u4/cvs/linux/net/ipv4/tcp_input.c,v
retrieving revision 1.135
retrieving revision 1.136
diff -u -r1.135 -r1.136
--- tcp_input.c 1998/11/07 10:54:42 1.135
+++ tcp_input.c 1998/11/07 14:36:18 1.136
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_input.c,v 1.135 1998/11/07 10:54:42 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.136 1998/11/07 14:36:18 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1517,7 +1517,7 @@
* - delay time <= 0.5 HZ
* - we don't have a window update to send
* - must send at least every 2 full sized packets
- * - must send an ACK if we have any SACKs
+ * - must send an ACK if we have any out of order data
*
* With an extra heuristic to handle loss of packet
* situations and also helping the sender leave slow
@@ -1530,8 +1530,8 @@
tcp_raise_window(sk) ||
/* We entered "quick ACK" mode or... */
tcp_in_quickack_mode(tp) ||
- /* We have pending SACKs */
- (tp->sack_ok && tp->num_sacks)) {
+ /* We have out of order data */
+ (skb_peek(&tp->out_of_order_queue) != NULL)) {
/* Then ack it now */
tcp_send_ack(sk);
} else {

Enjoy. BTW, I never noticed this because most the time when I'm
working on loss recovery on 2.1.x Linux both ends speak SACK. The fix
here for 2.1.x just turns the old SACK test into a more general test.
I'm hoping 2.2.x gets released soon so SACK can finally be widely
deployed.

Thanks a lot for pointing out this problem.

Later,
David S. Miller
davem@dm.cobaltmicro.com