From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
To: netdev@vger.kernel.org
Cc: Willem de Bruijn <willemb@google.com>
Subject: [PATCH RFC v2 02/12] sock: skb_copy_ubufs support for compound pages
Date: Wed, 22 Feb 2017 11:38:51 -0500 [thread overview]
Message-ID: <20170222163901.90834-3-willemdebruijn.kernel@gmail.com> (raw)
In-Reply-To: <20170222163901.90834-1-willemdebruijn.kernel@gmail.com>
From: Willem de Bruijn <willemb@google.com>
Refine skb_copy_ubufs to support compount pages. With upcoming TCP
and UDP zerocopy sendmsg, such fragments may appear.
These skbuffs can have both kernel and zerocopy fragments, e.g., when
corking. Avoid unnecessary copying of fragments that have no userspace
reference.
It is not safe to modify skb frags when the skbuff is shared. This
should not happen. Fail loudly if we find an unexpected edge case.
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
net/core/skbuff.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f3557958e9bf..67e4216fca01 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -944,6 +944,9 @@ EXPORT_SYMBOL_GPL(skb_morph);
* If this function is called from an interrupt gfp_mask() must be
* %GFP_ATOMIC.
*
+ * skb_shinfo(skb) can only be safely modified when not accessed
+ * concurrently. Fail if the skb is shared or cloned.
+ *
* Returns 0 on success or a negative error code on failure
* to allocate kernel memory to copy to.
*/
@@ -954,11 +957,29 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
struct page *page, *head = NULL;
struct ubuf_info *uarg = skb_shinfo(skb)->destructor_arg;
+ if (skb_shared(skb) || skb_cloned(skb)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
for (i = 0; i < num_frags; i++) {
u8 *vaddr;
+ unsigned int order = 0;
+ gfp_t mask = gfp_mask;
skb_frag_t *f = &skb_shinfo(skb)->frags[i];
- page = alloc_page(gfp_mask);
+ page = skb_frag_page(f);
+ if (page_count(page) == 1) {
+ skb_frag_ref(skb, i);
+ goto copy_done;
+ }
+
+ if (f->size > PAGE_SIZE) {
+ order = get_order(f->size);
+ mask |= __GFP_COMP;
+ }
+
+ page = alloc_pages(mask, order);
if (!page) {
while (head) {
struct page *next = (struct page *)page_private(head);
@@ -971,6 +992,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
memcpy(page_address(page),
vaddr + f->page_offset, skb_frag_size(f));
kunmap_atomic(vaddr);
+copy_done:
set_page_private(page, (unsigned long)head);
head = page;
}
--
2.11.0.483.g087da7b7c-goog
next prev parent reply other threads:[~2017-02-22 16:39 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-22 16:38 [PATCH RFC v2 00/12] socket sendmsg MSG_ZEROCOPY Willem de Bruijn
2017-02-22 16:38 ` [PATCH RFC v2 01/12] sock: allocate skbs from optmem Willem de Bruijn
2017-02-22 16:38 ` Willem de Bruijn [this message]
2017-02-22 20:33 ` [PATCH RFC v2 02/12] sock: skb_copy_ubufs support for compound pages Eric Dumazet
2017-02-23 1:51 ` Willem de Bruijn
2017-02-22 16:38 ` [PATCH RFC v2 03/12] sock: add generic socket zerocopy Willem de Bruijn
2017-02-22 16:38 ` [PATCH RFC v2 04/12] sock: enable sendmsg zerocopy Willem de Bruijn
2017-02-22 16:38 ` [PATCH RFC v2 05/12] sock: sendmsg zerocopy notification coalescing Willem de Bruijn
2017-02-22 16:38 ` [PATCH RFC v2 06/12] sock: sendmsg zerocopy ulimit Willem de Bruijn
2017-02-22 16:38 ` [PATCH RFC v2 07/12] sock: sendmsg zerocopy limit bytes per notification Willem de Bruijn
2017-02-22 16:38 ` [PATCH RFC v2 08/12] tcp: enable sendmsg zerocopy Willem de Bruijn
2017-02-22 16:38 ` [PATCH RFC v2 09/12] udp: " Willem de Bruijn
2017-02-22 16:38 ` [PATCH RFC v2 10/12] raw: enable sendmsg zerocopy with IP_HDRINCL Willem de Bruijn
2017-02-22 16:39 ` [PATCH RFC v2 11/12] packet: enable sendmsg zerocopy Willem de Bruijn
2017-02-22 16:39 ` [PATCH RFC v2 12/12] test: add sendmsg zerocopy tests Willem de Bruijn
2017-02-23 15:45 ` [PATCH RFC v2 00/12] socket sendmsg MSG_ZEROCOPY David Miller
2017-02-24 23:03 ` Alexei Starovoitov
2017-02-25 0:25 ` Willem de Bruijn
2017-02-27 18:57 ` Michael Kerrisk
2017-02-28 19:46 ` Andy Lutomirski
2017-02-28 20:43 ` Willem de Bruijn
[not found] ` <CAF=yD-K_0zO3pMeXf-UKGTsD4sNOdyN9KJkUb5MnCO_J5pisrA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-02-28 21:06 ` Andy Lutomirski
2017-03-01 3:28 ` David Miller
2017-03-01 3:43 ` Eric Dumazet
2017-03-02 19:26 ` Andy Lutomirski
2017-02-28 21:09 ` Andy Lutomirski
2017-02-28 21:28 ` Willem de Bruijn
2017-02-28 21:47 ` Eric Dumazet
[not found] ` <1488318476.9415.270.camel-XN9IlZ5yJG9HTL0Zs8A6p+yfmBU6pStAUsxypvmhUTTZJqsBc5GL+g@public.gmane.org>
2017-02-28 22:25 ` Andy Lutomirski
[not found] ` <CALCETrVQj1AEsLEGGkWW1zApGz6_x2rDmE0wz4ft+O5h07f_Ug-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-02-28 22:40 ` Eric Dumazet
2017-02-28 22:52 ` Andy Lutomirski
2017-02-28 23:22 ` Eric Dumazet
[not found] ` <1488324131.9415.278.camel-XN9IlZ5yJG9HTL0Zs8A6p+yfmBU6pStAUsxypvmhUTTZJqsBc5GL+g@public.gmane.org>
2017-03-01 0:28 ` Tom Herbert
[not found] ` <CALx6S357ssnbEu7CMrczEjiX25QYBJh3WG=w8KuAoxGQS4aKLA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-01 0:37 ` Eric Dumazet
2017-03-01 0:58 ` Willem de Bruijn
2017-03-01 1:50 ` Tom Herbert
2017-03-01 3:25 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170222163901.90834-3-willemdebruijn.kernel@gmail.com \
--to=willemdebruijn.kernel@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=willemb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).