Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 376105
b: refs/heads/master
c: 6ff50cd
h: refs/heads/master
i:
  376103: a799020
v: v3
  • Loading branch information
Eric Dumazet authored and David S. Miller committed May 16, 2013
1 parent e610f8b commit a983ca4
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5c4b274981950049af3330f14ed9e9aa25afb2fb
refs/heads/master: 6ff50cd55545d922f5c62776fe1feb38a9846168
22 changes: 21 additions & 1 deletion trunk/net/ipv4/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2887,6 +2887,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
unsigned int mss;
struct sk_buff *gso_skb = skb;
__sum16 newcheck;
bool ooo_okay, copy_destructor;

if (!pskb_may_pull(skb, sizeof(*th)))
goto out;
Expand Down Expand Up @@ -2927,10 +2928,18 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
goto out;
}

copy_destructor = gso_skb->destructor == tcp_wfree;
ooo_okay = gso_skb->ooo_okay;
/* All segments but the first should have ooo_okay cleared */
skb->ooo_okay = 0;

segs = skb_segment(skb, features);
if (IS_ERR(segs))
goto out;

/* Only first segment might have ooo_okay set */
segs->ooo_okay = ooo_okay;

delta = htonl(oldlen + (thlen + mss));

skb = segs;
Expand All @@ -2950,6 +2959,17 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
thlen, skb->csum));

seq += mss;
if (copy_destructor) {
skb->destructor = gso_skb->destructor;
skb->sk = gso_skb->sk;
/* {tcp|sock}_wfree() use exact truesize accounting :
* sum(skb->truesize) MUST be exactly be gso_skb->truesize
* So we account mss bytes of 'true size' for each segment.
* The last segment will contain the remaining.
*/
skb->truesize = mss;
gso_skb->truesize -= mss;
}
skb = skb->next;
th = tcp_hdr(skb);

Expand All @@ -2962,7 +2982,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
* is freed at TX completion, and not right now when gso_skb
* is freed by GSO engine
*/
if (gso_skb->destructor == tcp_wfree) {
if (copy_destructor) {
swap(gso_skb->sk, skb->sk);
swap(gso_skb->destructor, skb->destructor);
swap(gso_skb->truesize, skb->truesize);
Expand Down

0 comments on commit a983ca4

Please sign in to comment.