netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Willem de Bruijn <willemb@google.com>
To: netdev@vger.kernel.org
Cc: mst@redhat.com, jasowang@redhat.com,
	Willem de Bruijn <willemb@google.com>
Subject: [PATCH net-next RFC 01/10] sock: skb_copy_ubufs support for compound pages
Date: Thu, 20 Aug 2015 10:36:40 -0400	[thread overview]
Message-ID: <1440081408-12302-2-git-send-email-willemb@google.com> (raw)
In-Reply-To: <1440081408-12302-1-git-send-email-willemb@google.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 also combine kernel and user fragments, e.g., when
corking. Skip the copy for fragments that have only 1 (kernel)
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 b6a19ca..f1aa781 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -870,6 +870,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.
  */
@@ -880,11 +883,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(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);
@@ -897,6 +918,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.5.0.276.gf5e568e

  reply	other threads:[~2015-08-20 14:36 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-20 14:36 [PATCH net-next RFC 00/10] socket sendmsg MSG_ZEROCOPY Willem de Bruijn
2015-08-20 14:36 ` Willem de Bruijn [this message]
2015-08-20 14:36 ` [PATCH net-next RFC 02/10] sock: add sendmsg zerocopy Willem de Bruijn
2015-08-20 14:36 ` [PATCH net-next RFC 03/10] sock: enable " Willem de Bruijn
2015-08-20 14:36 ` [PATCH net-next RFC 04/10] sock: sendmsg zerocopy notification coalescing Willem de Bruijn
2015-08-20 14:36 ` [PATCH net-next RFC 05/10] tcp: enable sendmsg zerocopy Willem de Bruijn
2015-08-20 14:36 ` [PATCH net-next RFC 06/10] udp: " Willem de Bruijn
2015-08-20 14:36 ` [PATCH net-next RFC 07/10] raw: enable sendmsg zerocopy with hdrincl Willem de Bruijn
2015-08-20 14:36 ` [PATCH net-next RFC 08/10] packet: enable sendmsg zerocopy Willem de Bruijn
2015-08-20 14:36 ` [PATCH net-next RFC 09/10] sock: sendmsg zerocopy ulimit Willem de Bruijn
2015-08-20 22:56 ` [PATCH net-next RFC 00/10] socket sendmsg MSG_ZEROCOPY David Miller
2015-08-21  2:49   ` Willem de Bruijn
2015-08-21  5:17     ` 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=1440081408-12302-2-git-send-email-willemb@google.com \
    --to=willemb@google.com \
    --cc=jasowang@redhat.com \
    --cc=mst@redhat.com \
    --cc=netdev@vger.kernel.org \
    /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).