lkml.org 
[lkml]   [1996]   [Apr]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    SubjectPPP is slow (and so is TCP!) [with fixes]
    Date
    From

    I've spent the last couple of days giving the Linux TCP stack a hard stare,
    and I believe I have fixed a number of problems that have existed for
    quite some time. While I was at it I implemented a basic version
    of the fast retransmit algorithm for single dropped packets.

    For those who don't care about explanations, the patches are attached at
    the end of this message. They should result in improved performance for
    TCP in a variety of situations, including the notorious slow interactive
    PPP connections. On FTP gets from SOLARIS machines I see close to a factor
    of 2 increase in performance. On puts I see a smaller increase, but this
    is limited by the fact that both are now running pretty close to the maximum
    possible speed. There's still a bit of room for improvement, but I suspect
    that the remaining difficulty is just that Solaris has a lousy algorithm
    for estimating round trip times. FTP's to prep.ai.mit.edu now run
    full out for me.

    The attached patches should be applied over top of the pp87 patch that
    Linus posted to linux-kernel on April 10th. Sorry, I'd make it over 1.3.86,
    but I wanted to make it easier for Linus to put these patches into the
    distribution. If people really want a patch against 1.3.86 ask
    me about it.

    So, on with the explanations of the patches.

    First, let me address the numerous complaints that since 1.3.73 Linux
    PPP has been had a very bad interactive response, particularly with
    Solaris boxes. (I have been one of those people plagued by this problem,
    which was why I started looking into this stuff in the first place.)

    It turns out that the slow interactive performance is caused by the
    correct application of the Nagle algorithm on the senders side.
    The problem is that the Nagle algorithm requires that the
    send not send the next character until it gets the ack for the
    previous one. Since ACKs are delayed this really slows down
    the arrival of the response to interactively typed characters.

    There are two possible fixes:
    (1) Every time a character gets taken out of the receive buffer
    send an ACK to the other side informing them that the receive
    window has changed.
    (2) Assume that packets with the PSH flag set are part of an interactive
    connection, and don't delay ACKs for these packets.

    Fix (1) is what the pre 1.3.73 Linux stack did. It is also what
    the fix posted by Linus yesterday does. The problem with this fix
    is that it can result in multiple ACK packets for each packet
    we receive. It turns out that in order to get good aggregate performance
    we don't want to inform the other side about changes in the window
    unless we have received a packet or a zero window probe from the other side.
    Therefore, I followed the BSD lead and implemented fix (2) in these patches.

    Now, on to the real bugs. For quite some time (over a year) I have
    noticed that FTP gets from Solaris boxes never achieve full throughput,
    although if I look at the number of bytes crossing my PPP link the modem
    is running full bore. When we still had some SUNOS boxes around here
    I was always able to get 1.5-1.6 KBps across an FTP. After looking at
    reams of tcpdump output I think I have found and fixed the problems.

    First, I found that Solaris TCP was resending packets that it has already
    sent. Lots of them. In fact almost every packet is getting sent at
    least twice.

    It seems that the way we are dealing with out of sequence TCP packets
    was triggering a fast retransmit on the Solaris host when we didn't
    want it. In particular, a duplicate of a packet we had seen some time ago
    was being treated the same as a packet that ended either at or beyond
    the currently acknowledged sequence number.
    This was resulting in situations where we were sending
    three ACKs for a packet, which was resulting in the remote
    TCP sending extra copies of the next packet, which was resulting
    in our sending three ACKs for the next packet, and so on.
    This ends up cutting your bandwidth in half.
    I've fixed things by ignoring duplicate packets (those that are to
    the left of the last acked sequence number). Note that
    we still send ACKs if we get a duplicate of the last packet
    we saw, since otherwise a dropped ACK frame would stall the TCP.
    We're only ignoring really old packets with this change.

    Second, after I fixed the above problem I found that delayed ACKs
    where not being dealt with correctly. In particular we're
    violating RFC1122 in a couple of places:

    o It is required that an ACK packet that is delayed be delayed
    by no more than 0.5 seconds. The implementation can be forced
    to violate this easily. The problem is that every time new data
    arrives we reset the timeout for the ACK. An ACK can get delayed
    for as long as we continue to received data packets in order.

    o Second, an ACK SHOULD be sent every 2 full sized segments.
    We used to test for this, but somewhere along the line the
    test got dropped. This will mess up the RTT calculations
    for the remote side. I restored the test.

    After fixing these problems I was still seeing slow throughput,
    although now the link was sitting idle rather than having packet
    retransmits. To fix this I found that it was necessary to rewrite
    the implementation of receiver side silly window avoidance.
    The original code was following the RFC1122 suggested algorithm closely.
    This seems to interact badly with TCP implementations descended from BSD code,
    which uses a completely different algorithm for receiver side
    silly window avoidance. I've changed things to follow the BSD lead
    here as well. Strictly speaking this does not violate RFC1122, and
    it leads to much better performance in the tests I've been able
    to perform so far.

    While I was mucking around under the hood and trying to get better
    performance, I decided I should implement a "fast retransmit"
    algorithm as well. It turned out to be fairly straight forward,
    so I've included this in the patch as well. This isn't quite
    full blown fast retransmit, but it still makes quite a difference.

    So, without further ado, here are the patches, uuencoded and gzipped.

    -- eric

    ---------------------------------------------------------------------------
    Eric Schenk www: http://www.cs.toronto.edu/~schenk
    Department of Computer Science email: schenk@cs.toronto.edu
    University of Toronto

    begin 644 tcp_patch.1.3.p87.gz
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
    5'!3\H*EY)?BXI!(7`(.%M$PL0P``
    `
    end


    \
     
     \ /
      Last update: 2005-03-22 13:37    [W:0.047 / U:34.004 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site