]> git.baikalelectronics.ru Git - kernel.git/commitdiff
mptcp: attempt coalescing when moving skbs to mptcp rx queue
authorFlorian Westphal <fw@strlen.de>
Mon, 25 May 2020 21:41:13 +0000 (23:41 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 27 May 2020 03:29:32 +0000 (20:29 -0700)
We can try to coalesce skbs we take from the subflows rx queue with the
tail of the mptcp rx queue.

If successful, the skb head can be discarded early.

We can also free the skb extensions, we do not access them after this.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mptcp/protocol.c

index ba9d3d5c625f7aee9d0f32174bddd222920c538a..b2c8b57e7942acb2224ff540e6998ef476f0e216 100644 (file)
@@ -144,12 +144,29 @@ static void __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,
                             unsigned int offset, size_t copy_len)
 {
        struct sock *sk = (struct sock *)msk;
+       struct sk_buff *tail;
 
        __skb_unlink(skb, &ssk->sk_receive_queue);
-       skb_set_owner_r(skb, sk);
-       __skb_queue_tail(&sk->sk_receive_queue, skb);
 
+       skb_ext_reset(skb);
+       skb_orphan(skb);
        msk->ack_seq += copy_len;
+
+       tail = skb_peek_tail(&sk->sk_receive_queue);
+       if (offset == 0 && tail) {
+               bool fragstolen;
+               int delta;
+
+               if (skb_try_coalesce(tail, skb, &fragstolen, &delta)) {
+                       kfree_skb_partial(skb, fragstolen);
+                       atomic_add(delta, &sk->sk_rmem_alloc);
+                       sk_mem_charge(sk, delta);
+                       return;
+               }
+       }
+
+       skb_set_owner_r(skb, sk);
+       __skb_queue_tail(&sk->sk_receive_queue, skb);
        MPTCP_SKB_CB(skb)->offset = offset;
 }