Re: [patch] TCP/IP delacks disabled with MPI

Andrea Arcangeli (andrea@suse.de)
Fri, 21 May 1999 17:15:31 +0200 (CEST)


On Fri, 21 May 1999, Josip Loncaric wrote:

>My understanding is that Linux TCP incorrectly handles the slow start
>algorithm because it does not count the _number_ of packets that each
>ACK represents. [..]

So you think that the improvement of my patch cames from the increase of
the number of ack received that will cause a faster grow of cwnd on the
sender side.

But, are you sure that at every ack we should check the number of packets
that each ACK represents before increasing cwnd? It's not obvious reading
draft-ietf-tcpimpl-cong-control-01.txt:

[..]
During slow start, a TCP increments cwnd by at most MSS bytes for
each ACK received that acknowledges new data. [..]

And should we force an ack at the second not acked packet queued (as my
new patch does for only NODELAY) or after we have 2*MSS data queued but
not acked yet (as stock 2.2.9 does)? Maybe this is the real problem. This
is what I read from rfc1122:

A TCP SHOULD implement a delayed ACK, but an ACK should not
be excessively delayed; in particular, the delay MUST be
less than 0.5 seconds, and in a stream of full-sized
segments there SHOULD be an ACK for at least every second
segment.

What does it mean "at least every second segment"?

2.2.9 interpret this as "at least after 2*MSS of not-acked data is just
queued in the receiver"....

If 2.2.9 is wrong about that, this is my fix (that hopefully will address
automagically also the cwnd increase in the MPI case):

Index: linux/net/ipv4/tcp_input.c
===================================================================
RCS file: /var/cvs/linux/net/ipv4/tcp_input.c,v
retrieving revision 1.1.1.11
diff -u -r1.1.1.11 tcp_input.c
--- linux/net/ipv4/tcp_input.c 1999/05/16 20:56:05 1.1.1.11
+++ linux/net/ipv4/tcp_input.c 1999/05/21 15:11:12
@@ -1575,6 +1591,25 @@
}
}

+static __inline__ int tcp_nr_packets_not_acked(int nr, struct sock * sk,
+ struct tcp_opt * tp)
+{
+ int __nr = 0;
+ struct sk_buff * skb = (struct sk_buff *) &sk->receive_queue;
+
+ while ((skb = skb->prev) != (struct sk_buff *) &sk->receive_queue)
+ {
+ if (TCP_SKB_CB(skb)->end_seq > tp->last_ack_sent)
+ {
+ if (++__nr >= nr)
+ return 1;
+ }
+ else
+ break;
+ }
+ return 0;
+}
+
/*
* Check if sending an ack is needed.
*/
@@ -1597,13 +1632,13 @@
*/

/* Two full frames received or... */
- if (((tp->rcv_nxt - tp->rcv_wup) >= tp->rcv_mss * MAX_DELAY_ACK) ||
+ if (tcp_nr_packets_not_acked(2, sk, tp) ||
/* We will update the window "significantly" or... */
tcp_raise_window(sk) ||
/* We entered "quick ACK" mode or... */
tcp_in_quickack_mode(tp) ||
/* We have out of order data */
- (skb_peek(&tp->out_of_order_queue) != NULL)) {
+ !skb_queue_empty(&tp->out_of_order_queue)) {
/* Then ack it now */
tcp_send_ack(sk);
} else {

Andrea Arcangeli

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/