From: Jason Wang <jasowang@redhat.com>
To: Michael Dalton <mwdalton@google.com>,
"David S. Miller" <davem@davemloft.net>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
netdev@vger.kernel.org, Daniel Borkmann <dborkman@redhat.com>,
virtualization@lists.linux-foundation.org,
Eric Dumazet <edumazet@google.com>
Subject: Re: [PATCH net-next] virtio_net: migrate mergeable rx buffers to page frag allocators
Date: Tue, 29 Oct 2013 14:27:11 +0800 [thread overview]
Message-ID: <526F553F.8060708@redhat.com> (raw)
In-Reply-To: <1383000258-1458-1-git-send-email-mwdalton@google.com>
On 10/29/2013 06:44 AM, Michael Dalton wrote:
> The virtio_net driver's mergeable receive buffer allocator
> uses 4KB packet buffers. For MTU-sized traffic, SKB truesize
> is > 4KB but only ~1500 bytes of the buffer is used to store
> packet data, reducing the effective TCP window size
> substantially. This patch addresses the performance concerns
> with mergeable receive buffers by allocating MTU-sized packet
> buffers using page frag allocators. If more than MAX_SKB_FRAGS
> buffers are needed, the SKB frag_list is used.
>
> Signed-off-by: Michael Dalton <mwdalton@google.com>
Do you have any perf numberf of this patch? Have a glance of the patch,
looks like it will hurt the performance of large GSO packet. Always
allocating 1500 bytes mean a virtqueue can only hold about 4 full size
gso packets, and frag list will introduce extra overheads on skb
allocation. I just test it on my desktop, performance of full size gso
packet drops about 10%.
Mergeable buffer is a good balance between performance and the space it
occupies. If you just want a ~1500 bytes packet to be received, you can
just disable the mergeable buffer and just use small packet.
Alternatively, a simpler way is just use build_skb() and head frag to
build the skb directly on the page for medium size packets (small
packets were still copied) like following patch (may need more work
since vnet header is too short for NET_SKB_PAD). This can reduce the
truesize while keep the performance for large GSO packet.
---
drivers/net/virtio_net.c | 48
++++++++++++++++++++++++++++++---------------
1 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 3c23fdc..4c7ad89 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -239,16 +239,12 @@ static struct sk_buff *page_to_skb(struct
receive_queue *rq,
struct skb_vnet_hdr *hdr;
unsigned int copy, hdr_len, offset;
char *p;
+ int skb_size = SKB_DATA_ALIGN(len) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ bool frag;
p = page_address(page);
- /* copy small packet so we can reuse these pages for small data */
- skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
- if (unlikely(!skb))
- return NULL;
-
- hdr = skb_vnet_hdr(skb);
-
if (vi->mergeable_rx_bufs) {
hdr_len = sizeof hdr->mhdr;
offset = hdr_len;
@@ -257,18 +253,38 @@ static struct sk_buff *page_to_skb(struct
receive_queue *rq,
offset = sizeof(struct padded_vnet_hdr);
}
- memcpy(hdr, p, hdr_len);
-
len -= hdr_len;
p += offset;
- copy = len;
- if (copy > skb_tailroom(skb))
- copy = skb_tailroom(skb);
- memcpy(skb_put(skb, copy), p, copy);
+ frag = (len > GOOD_COPY_LEN) && (skb_size <= PAGE_SIZE) &&
+ vi->mergeable_rx_bufs;
+ if (frag) {
+ skb = build_skb(page_address(page), skb_size);
+ if (unlikely(!skb))
+ return NULL;
+
+ skb_reserve(skb, offset);
+ skb_put(skb, len);
+ len = 0;
+ } else {
+ /* copy small packet so we can reuse these pages for small data
+ */
+ skb = netdev_alloc_skb_ip_align(vi->dev, GOOD_COPY_LEN);
+ if (unlikely(!skb))
+ return NULL;
+
+ copy = len;
+ if (copy > skb_tailroom(skb))
+ copy = skb_tailroom(skb);
+ memcpy(skb_put(skb, copy), p, copy);
+
+ len -= copy;
+ offset += copy;
+ }
+
+ hdr = skb_vnet_hdr(skb);
- len -= copy;
- offset += copy;
+ memcpy(hdr, page_address(page), hdr_len);
/*
* Verify that we can indeed put this data into a skb.
@@ -288,7 +304,7 @@ static struct sk_buff *page_to_skb(struct
receive_queue *rq,
offset = 0;
}
- if (page)
+ if (page && !frag)
give_pages(rq, page);
return skb;
--
1.7.1
next prev parent reply other threads:[~2013-10-29 6:27 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-28 22:44 [PATCH net-next] virtio_net: migrate mergeable rx buffers to page frag allocators Michael Dalton
2013-10-28 23:19 ` Eric Dumazet
2013-10-29 3:57 ` David Miller
2013-10-29 19:12 ` Michael S. Tsirkin
2013-10-29 7:30 ` Daniel Borkmann
2013-10-29 1:51 ` Rusty Russell
2013-10-29 6:27 ` Jason Wang [this message]
2013-10-29 18:44 ` Eric Northup
2013-10-29 19:05 ` Michael Dalton
2013-10-29 19:17 ` Michael S. Tsirkin
2013-10-30 4:41 ` Jason Wang
2013-10-29 19:05 ` Michael S. Tsirkin
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=526F553F.8060708@redhat.com \
--to=jasowang@redhat.com \
--cc=davem@davemloft.net \
--cc=dborkman@redhat.com \
--cc=edumazet@google.com \
--cc=mst@redhat.com \
--cc=mwdalton@google.com \
--cc=netdev@vger.kernel.org \
--cc=virtualization@lists.linux-foundation.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).