• Neal Cardwell's avatar
    tcp: fix indefinite deferral of RTO with SACK reneging · 3d2af9cc
    Neal Cardwell authored
    This commit fixes a bug that can cause a TCP data sender to repeatedly
    defer RTOs when encountering SACK reneging.
    
    The bug is that when we're in fast recovery in a scenario with SACK
    reneging, every time we get an ACK we call tcp_check_sack_reneging()
    and it can note the apparent SACK reneging and rearm the RTO timer for
    srtt/2 into the future. In some SACK reneging scenarios that can
    happen repeatedly until the receive window fills up, at which point
    the sender can't send any more, the ACKs stop arriving, and the RTO
    fires at srtt/2 after the last ACK. But that can take far too long
    (O(10 secs)), since the connection is stuck in fast recovery with a
    low cwnd that cannot grow beyond ssthresh, even if more bandwidth is
    available.
    
    This fix changes the logic in tcp_check_sack_reneging() to only rearm
    the RTO timer if data is cumulatively ACKed, indicating forward
    progress. This avoids this kind of nearly infinite loop of RTO timer
    re-arming. In addition, this meets the goals of
    tcp_check_sack_reneging() in handling Windows TCP behavior that looks
    temporarily like SACK reneging but is not really.
    
    Many thanks to Jakub Kicinski and Neil Spring, who reported this issue
    and provided critical packet traces that enabled root-causing this
    issue. Also, many thanks to Jakub Kicinski for testing this fix.
    
    Fixes: 5ae344c9 ("tcp: reduce spurious retransmits due to transient SACK reneging")
    Reported-by: default avatarJakub Kicinski <kuba@kernel.org>
    Reported-by: default avatarNeil Spring <ntspring@fb.com>
    Signed-off-by: default avatarNeal Cardwell <ncardwell@google.com>
    Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
    Cc: Yuchung Cheng <ycheng@google.com>
    Tested-by: default avatarJakub Kicinski <kuba@kernel.org>
    Link: https://lore.kernel.org/r/20221021170821.1093930-1-ncardwell.kernel@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    3d2af9cc
tcp_input.c 202 KB