|
@@ -18,6 +18,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
|
|
|
netdev_features_t features)
|
|
|
{
|
|
|
struct sk_buff *segs = ERR_PTR(-EINVAL);
|
|
|
+ unsigned int sum_truesize = 0;
|
|
|
struct tcphdr *th;
|
|
|
unsigned int thlen;
|
|
|
unsigned int seq;
|
|
@@ -102,13 +103,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
|
|
|
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;
|
|
|
+ sum_truesize += skb->truesize;
|
|
|
}
|
|
|
skb = skb->next;
|
|
|
th = tcp_hdr(skb);
|
|
@@ -125,7 +120,9 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
|
|
|
if (copy_destructor) {
|
|
|
swap(gso_skb->sk, skb->sk);
|
|
|
swap(gso_skb->destructor, skb->destructor);
|
|
|
- swap(gso_skb->truesize, skb->truesize);
|
|
|
+ sum_truesize += skb->truesize;
|
|
|
+ atomic_add(sum_truesize - gso_skb->truesize,
|
|
|
+ &skb->sk->sk_wmem_alloc);
|
|
|
}
|
|
|
|
|
|
delta = htonl(oldlen + (skb_tail_pointer(skb) -
|