Commit dbe4fec2 authored by Xuan Zhuo's avatar Xuan Zhuo Committed by Jakub Kicinski
Browse files

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: default avatarXuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ad4858be
Loading
Loading
Loading
Loading
+14 −15
Original line number Diff line number Diff line
@@ -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;
	return page_address(*page) + VIRTIO_XDP_HEADROOM;
}

static struct sk_buff *receive_mergeable(struct net_device *dev,