• David S. Miller's avatar
    [TCP]: Fix sk_forward_alloc assertion failures with TSO. · c37fa339
    David S. Miller authored
    do_tcp_sendpages() needs to do skb->truesize et al.
    accounting just like tcp_sendmsg() does.
    
    tcp_sendmsg() works by gradually adjusting these
    accounting knobs as user data is copied into the
    packet.
    
    do_tcp_sendpages() works differently, when it allocates
    a new SKB it optimistically adds in tp->mss_cache to
    these values and then makes no adjustments at all as
    pages are tacked onto the packet.
    
    This does not work at all if tcp_sendmsg() queues a
    packet onto the send queue, and then do_tcp_sendpages()
    attaches pages onto the end of that SKB.  We are left
    with a very inaccurate skb->truesize in that case.
    
    Consequently, if we were building a TSO frame and it
    gets partially ACK'd, then since skb->truesize is too
    small tcp_trim_skb() will potentially underflow it's
    value and all the accounting becomes corrupted.
    
    This is usually seen as sk->sk_forward_alloc being
    negative at socket destroy time, which triggers an
    assertion check.
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    c37fa339
tcp.c 63 KB