From: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Date: 2017-12-23 00:00:24
From: Willem de Bruijn <willemb@google.com>
1/4 is a small optimization follow-up to the earlier fix to skb_segment:
check skb state once per skb, instead of once per frag.
2/4 makes behavior more consistent between standard and zerocopy send:
set the PSH bit when hitting MAX_SKB_FRAGS. This helps GRO.
3/4 resolves a surprising inconsistency in notification:
because small packets were not stored in frags, they would not set
the copied error code over loopback. This change also optimizes
the path by removing copying and making tso_fragment cheaper.
4/4 follows-up to 3/4 by no longer allocated now unused memory.
this was actually already in RFC patches, but dropped as I pared
down the patch set during revisions.
Willem de Bruijn (4):
skbuff: in skb_segment, call zerocopy functions once per nskb
tcp: push full zerocopy packets
tcp: place all zerocopy payload in frags
tcp: do not allocate linear memory for zerocopy skbs
net/core/skbuff.c | 14 +++++++++-----
net/ipv4/tcp.c | 24 +++++++++++++++---------
2 files changed, 24 insertions(+), 14 deletions(-)
--
2.15.1.620.gb9897f4670-goog
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Date: 2017-12-23 00:00:24
From: Willem de Bruijn <willemb@google.com>
This is a net-next follow-up to commit 268b79067942 ("skbuff: orphan
frags before zerocopy clone"), which fixed a bug in net, but added a
call to skb_zerocopy_clone at each frag to do so.
When segmenting skbs with user frags, either the user frags must be
replaced with private copies and uarg released, or the uarg must have
its refcount increased for each new skb.
skb_orphan_frags does the first, except for cases that can handle
reference counting. skb_zerocopy_clone then does the second.
Call these once per nskb, instead of once per frag.
That is, in the common case. With a frag list, also refresh when the
origin skb (frag_skb) changes.
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
net/core/skbuff.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Date: 2017-12-23 00:00:26
From: Willem de Bruijn <willemb@google.com>
Skbs that reach MAX_SKB_FRAGS cannot be extended further. Do the
same for zerocopy frags as non-zerocopy frags and set the PSH bit.
This improves GRO assembly.
Suggested-by: Eric Dumazet <redacted>
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
net/ipv4/tcp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Date: 2017-12-23 00:00:27
From: Willem de Bruijn <willemb@google.com>
Zerocopy payload is now always stored in frags, and space for headers
is reversed, so this memory is unused.
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
net/ipv4/tcp.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
@@ -1104,12 +1104,15 @@ static int linear_payload_sz(bool first_skb)return0;}-staticintselect_size(conststructsock*sk,boolsg,boolfirst_skb)+staticintselect_size(conststructsock*sk,boolsg,boolfirst_skb,boolzc){conststructtcp_sock*tp=tcp_sk(sk);inttmp=tp->mss_cache;if(sg){+if(zc)+return0;+if(sk_can_gso(sk)){tmp=linear_payload_sz(first_skb);}else{
@@ -1282,6 +1285,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)if(copy<=0||!tcp_skb_can_collapse_to(skb)){boolfirst_skb;+intlinear;new_segment:/* Allocate new segment. If the interface is SG,
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Date: 2017-12-23 00:00:28
From: Willem de Bruijn <willemb@google.com>
This avoids an unnecessary copy of 1-2KB and improves tso_fragment,
which has to fall back to tcp_fragment if skb->len != skb_data_len.
It also avoids a surprising inconsistency in notifications:
Zerocopy packets sent over loopback have their frags copied, so set
SO_EE_CODE_ZEROCOPY_COPIED in the notification. But this currently
does not happen for small packets, because when all data fits in the
linear fragment, data is not copied in skb_orphan_frags_rx.
Reported-by: Tom Deseyn <redacted>
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
net/ipv4/tcp.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
@@ -1325,13 +1326,13 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)copy=msg_data_left(msg);/* Where to copy to? */-if(skb_availroom(skb)>0){+if(skb_availroom(skb)>0&&!zc){/* We have some space in skb head. Superb! */copy=min_t(int,copy,skb_availroom(skb));err=skb_add_data_nocache(sk,skb,&msg->msg_iter,copy);if(err)gotodo_fault;-}elseif(!uarg||!uarg->zerocopy){+}elseif(!zc){boolmerge=true;inti=skb_shinfo(skb)->nr_frags;structpage_frag*pfrag=sk_page_frag(sk);
From: David Miller <davem@davemloft.net> Date: 2017-12-27 21:45:53
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Fri, 22 Dec 2017 19:00:16 -0500
From: Willem de Bruijn <willemb@google.com>
1/4 is a small optimization follow-up to the earlier fix to skb_segment:
check skb state once per skb, instead of once per frag.
2/4 makes behavior more consistent between standard and zerocopy send:
set the PSH bit when hitting MAX_SKB_FRAGS. This helps GRO.
3/4 resolves a surprising inconsistency in notification:
because small packets were not stored in frags, they would not set
the copied error code over loopback. This change also optimizes
the path by removing copying and making tso_fragment cheaper.
4/4 follows-up to 3/4 by no longer allocated now unused memory.
this was actually already in RFC patches, but dropped as I pared
down the patch set during revisions.