lkml.org 
[lkml]   [2020]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.8 052/633] tcp: fix to update snd_wl1 in bulk receiver fast path
    Date
    From: Neal Cardwell <ncardwell@google.com>

    [ Upstream commit 18ded910b589839e38a51623a179837ab4cc3789 ]

    In the header prediction fast path for a bulk data receiver, if no
    data is newly acknowledged then we do not call tcp_ack() and do not
    call tcp_ack_update_window(). This means that a bulk receiver that
    receives large amounts of data can have the incoming sequence numbers
    wrap, so that the check in tcp_may_update_window fails:
    after(ack_seq, tp->snd_wl1)

    If the incoming receive windows are zero in this state, and then the
    connection that was a bulk data receiver later wants to send data,
    that connection can find itself persistently rejecting the window
    updates in incoming ACKs. This means the connection can persistently
    fail to discover that the receive window has opened, which in turn
    means that the connection is unable to send anything, and the
    connection's sending process can get permanently "stuck".

    The fix is to update snd_wl1 in the header prediction fast path for a
    bulk data receiver, so that it keeps up and does not see wrapping
    problems.

    This fix is based on a very nice and thorough analysis and diagnosis
    by Apollon Oikonomopoulos (see link below).

    This is a stable candidate but there is no Fixes tag here since the
    bug predates current git history. Just for fun: looks like the bug
    dates back to when header prediction was added in Linux v2.1.8 in Nov
    1996. In that version tcp_rcv_established() was added, and the code
    only updates snd_wl1 in tcp_ack(), and in the new "Bulk data transfer:
    receiver" code path it does not call tcp_ack(). This fix seems to
    apply cleanly at least as far back as v3.2.

    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Signed-off-by: Neal Cardwell <ncardwell@google.com>
    Reported-by: Apollon Oikonomopoulos <apoikos@dmesg.gr>
    Tested-by: Apollon Oikonomopoulos <apoikos@dmesg.gr>
    Link: https://www.spinics.net/lists/netdev/msg692430.html
    Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
    Acked-by: Yuchung Cheng <ycheng@google.com>
    Signed-off-by: Eric Dumazet <edumazet@google.com>
    Link: https://lore.kernel.org/r/20201022143331.1887495-1-ncardwell.kernel@gmail.com
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/ipv4/tcp_input.c | 2 ++
    1 file changed, 2 insertions(+)

    --- a/net/ipv4/tcp_input.c
    +++ b/net/ipv4/tcp_input.c
    @@ -5716,6 +5716,8 @@ void tcp_rcv_established(struct sock *sk
    tcp_data_snd_check(sk);
    if (!inet_csk_ack_scheduled(sk))
    goto no_ack;
    + } else {
    + tcp_update_wl(tp, TCP_SKB_CB(skb)->seq);
    }

    __tcp_ack_snd_check(sk, 0);

    \
     
     \ /
      Last update: 2020-10-27 18:10    [W:2.902 / U:0.912 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site