Messages in this thread | | | Date | Thu, 10 Sep 1998 13:17:18 -0400 (EDT) | From | "Vijay G. Bharadwaj" <> | Subject | Re: [PATCH] Re: Very poor TCP/SACK performance |
| |
I see I made some stupid claims here, let me apologize and clarify...
On Thu, 10 Sep 1998, Savochkin Andrey Vladimirovich wrote:
> I can't comment the first two problems but both the explanation > and the fix for the third problem is wrong. > 1. I suppose you don't remember the RFC statements about zero window > probing at all. TCP of course isn't obliged to always accept one byte of > data.
RFC 793, page 42, "Managing the window" states that the *sending* TCP should always accept one byte of new data to send. I ended up suggesting that the *receiving* TCP should always accept a new byte, which was wrong. However the problem pointed out in Linux still exists (I have observed it in the lab on a number of occasions). Here's what happens:
1) Sender sends a lot of data, fills up window 2) Receiver advertises zero window. 3) Sender sends a probe, and the probe has one new octet 4) Receiver accepts this octet, and still advertises zero window (In older versions, the receive_window wraps and so opens up to 64K, but not in newer versions, as you observe and as I pointed out) 5) Back to step 3.
This goes on for a long time (does SWS avoidance contribute by not advertising a window of (MSS-1)? I don't know and I haven't looked)
I first observed this on a fast ethernet to a solaris 2.6 box, with a very slow app on the linux box.
Another mistake I made - neither RFC 793 nor 1122 states what should be in a zero window probe. A *keepalive* should contain a garbage octet (but Sun I think sends a new byte; I remember a flamewar on tcp-impl). So a probe with one new octet is legal.
Third mistake - related to the first one - I was wrong to say this change violates any RFC.
> 2. Problem with window wrapping below zero was fixed ages ago.
Agreed. I pointed that out in my mail. However, it doesn't fix the above problem. Also, with this check in, we may not need that check for (win < 0) in tcp_receive_window() any more (I don't see any other code path that can cause the wrap)
> 3. The suggested fix wastes CPU cycles in a speed critical part. > It has no sense to do extra comparisons when we've just checked > that `TCP_SKB_CB(skb)->seq == tp->rcv_nxt'. And no > sequence check is required for the bulk sender path. > The only thing that may have a sense is to move the check > `!before(TCP_SKB_CB(skb)->seq, tp->rcv_wup + tp->rcv_wnd)' > just before the socket space check.
I agree with this one. No sequence check is required for the data sender part. And what you suggest is correct, the check for !before(..) (isn't this identical to the !tcp_sequence() check?) should be moved to before the socket space check, because socket space is usually available even if window is zero, due to the way the offered window is chosen.
But the check is still required, due to the problem outlined above. There is simply no other check in the code to reject segments received into a zero window.
Regards,
-Vijay
PS - I got an interesting "TCP stall" with a Linux client in the problem case I mentioned. The wrapped receive window caused the receiver to advertize a 64K window, which was not a multiple of MSS. So when this window filled up, the last remaining chunk was not MSS-sized. When NT4.0 sees an advertized window less than MSS, it waits for an interval equal to a retransmission timeout before sending a packet...
- 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/faq.html
| |