tcp: Do not tack on TSO data to non-TSO packet
If a socket starts out on a non-TSO route, and then switches to a TSO route, then we will tack on data to the tail of the tx queue even if it started out life as non-TSO. This is suboptimal because all of it will then be copied and checksummed unnecessarily. This patch fixes this by ensuring that skb->ip_summed is set to CHECKSUM_PARTIAL before appending extra data beyond the MSS. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8e5b9dda99
commit
6828b92bd2
|
@ -903,13 +903,17 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
|
||||||
iov++;
|
iov++;
|
||||||
|
|
||||||
while (seglen > 0) {
|
while (seglen > 0) {
|
||||||
int copy;
|
int copy = 0;
|
||||||
|
int max = size_goal;
|
||||||
|
|
||||||
skb = tcp_write_queue_tail(sk);
|
skb = tcp_write_queue_tail(sk);
|
||||||
|
if (tcp_send_head(sk)) {
|
||||||
|
if (skb->ip_summed == CHECKSUM_NONE)
|
||||||
|
max = mss_now;
|
||||||
|
copy = max - skb->len;
|
||||||
|
}
|
||||||
|
|
||||||
if (!tcp_send_head(sk) ||
|
if (copy <= 0) {
|
||||||
(copy = size_goal - skb->len) <= 0) {
|
|
||||||
|
|
||||||
new_segment:
|
new_segment:
|
||||||
/* Allocate new segment. If the interface is SG,
|
/* Allocate new segment. If the interface is SG,
|
||||||
* allocate skb fitting to single page.
|
* allocate skb fitting to single page.
|
||||||
|
@ -930,6 +934,7 @@ new_segment:
|
||||||
|
|
||||||
skb_entail(sk, skb);
|
skb_entail(sk, skb);
|
||||||
copy = size_goal;
|
copy = size_goal;
|
||||||
|
max = size_goal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to append data to the end of skb. */
|
/* Try to append data to the end of skb. */
|
||||||
|
@ -1028,7 +1033,7 @@ new_segment:
|
||||||
if ((seglen -= copy) == 0 && iovlen == 0)
|
if ((seglen -= copy) == 0 && iovlen == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (skb->len < size_goal || (flags & MSG_OOB))
|
if (skb->len < max || (flags & MSG_OOB))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (forced_push(tp)) {
|
if (forced_push(tp)) {
|
||||||
|
|
Loading…
Reference in New Issue