[TCP]: Fix sk_forward_alloc assertion failures with TSO.
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: David S. Miller <davem@davemloft.net>
Showing
Please register or sign in to comment