summaryrefslogtreecommitdiff
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
authorXuan Zhuo <xuanzhuo@linux.alibaba.com>2023-05-08 14:14:05 +0800
committerJakub Kicinski <kuba@kernel.org>2023-05-09 19:44:26 -0700
commitdbe4fec2447dd215964aad88b0e06f96c6958ee9 (patch)
treed8c403b313f42b9f7f7290597078119e854ad4a6 /drivers/net/virtio_net.c
parentad4858beb824aeba53deeae660ea7fab9e624bc0 (diff)
virtio_net: optimize mergeable_xdp_get_buf()
The previous patch, in order to facilitate review, I do not do any modification. This patch has made some optimization on the top. * remove some repeated logics in this function. * add fast check for passing without any alloc. Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index a75745dfe2e1..3c3602982ea2 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1196,6 +1196,11 @@ static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
*/
*frame_sz = truesize;
+ if (likely(headroom >= virtnet_get_headroom(vi) &&
+ (*num_buf == 1 || xdp_prog->aux->xdp_has_frags))) {
+ return page_address(*page) + offset;
+ }
+
/* This happens when headroom is not enough because
* of the buffer was prefilled before XDP is set.
* This should only happen for the first several packets.
@@ -1204,22 +1209,15 @@ static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
* support it, and we don't want to bother users who are
* using xdp normally.
*/
- if (!xdp_prog->aux->xdp_has_frags &&
- (*num_buf > 1 || headroom < virtnet_get_headroom(vi))) {
+ if (!xdp_prog->aux->xdp_has_frags) {
/* linearize data for XDP */
xdp_page = xdp_linearize_page(rq, num_buf,
*page, offset,
VIRTIO_XDP_HEADROOM,
len);
- *frame_sz = PAGE_SIZE;
-
if (!xdp_page)
return NULL;
- offset = VIRTIO_XDP_HEADROOM;
-
- put_page(*page);
- *page = xdp_page;
- } else if (unlikely(headroom < virtnet_get_headroom(vi))) {
+ } else {
xdp_room = SKB_DATA_ALIGN(VIRTIO_XDP_HEADROOM +
sizeof(struct skb_shared_info));
if (*len + xdp_room > PAGE_SIZE)
@@ -1231,14 +1229,15 @@ static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
memcpy(page_address(xdp_page) + VIRTIO_XDP_HEADROOM,
page_address(*page) + offset, *len);
- *frame_sz = PAGE_SIZE;
- offset = VIRTIO_XDP_HEADROOM;
-
- put_page(*page);
- *page = xdp_page;
}
- return page_address(*page) + offset;
+ *frame_sz = PAGE_SIZE;
+
+ put_page(*page);
+
+ *page = xdp_page;
+
+ return page_address(*page) + VIRTIO_XDP_HEADROOM;
}
static struct sk_buff *receive_mergeable(struct net_device *dev,