All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v3 00/15] virtio_net: refactor xdp codes
@ 2023-04-23 10:57 ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

Due to historical reasons, the implementation of XDP in virtio-net is relatively
chaotic. For example, the processing of XDP actions has two copies of similar
code. Such as page, xdp_page processing, etc.

The purpose of this patch set is to refactor these code. Reduce the difficulty
of subsequent maintenance. Subsequent developers will not introduce new bugs
because of some complex logical relationships.

In addition, the supporting to AF_XDP that I want to submit later will also need
to reuse the logic of XDP, such as the processing of actions, I don't want to
introduce a new similar code. In this way, I can reuse these codes in the
future.

Please review.

Thanks.

v2:
    1. re-split to make review more convenient

v1:
    1. fix some variables are uninitialized


Xuan Zhuo (15):
  virtio_net: mergeable xdp: put old page immediately
  virtio_net: introduce mergeable_xdp_get_buf()
  virtio_net: optimize mergeable_xdp_get_buf()
  virtio_net: introduce virtnet_xdp_handler() to seprate the logic of
    run xdp
  virtio_net: separate the logic of freeing xdp shinfo
  virtio_net: separate the logic of freeing the rest mergeable buf
  virtio_net: auto release xdp shinfo
  virtio_net: introduce receive_mergeable_xdp()
  virtio_net: merge: remove skip_xdp
  virtio_net: introduce receive_small_xdp()
  virtio_net: small: optimize code
  virtio_net: small: optimize code
  virtio_net: small: remove skip_xdp
  virtio_net: introduce receive_small_build_xdp
  virtio_net: introduce virtnet_build_skb()

 drivers/net/virtio_net.c | 659 +++++++++++++++++++++++----------------
 1 file changed, 386 insertions(+), 273 deletions(-)

-- 
2.32.0.3.g01195cf9f


^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 00/15] virtio_net: refactor xdp codes
@ 2023-04-23 10:57 ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

Due to historical reasons, the implementation of XDP in virtio-net is relatively
chaotic. For example, the processing of XDP actions has two copies of similar
code. Such as page, xdp_page processing, etc.

The purpose of this patch set is to refactor these code. Reduce the difficulty
of subsequent maintenance. Subsequent developers will not introduce new bugs
because of some complex logical relationships.

In addition, the supporting to AF_XDP that I want to submit later will also need
to reuse the logic of XDP, such as the processing of actions, I don't want to
introduce a new similar code. In this way, I can reuse these codes in the
future.

Please review.

Thanks.

v2:
    1. re-split to make review more convenient

v1:
    1. fix some variables are uninitialized


Xuan Zhuo (15):
  virtio_net: mergeable xdp: put old page immediately
  virtio_net: introduce mergeable_xdp_get_buf()
  virtio_net: optimize mergeable_xdp_get_buf()
  virtio_net: introduce virtnet_xdp_handler() to seprate the logic of
    run xdp
  virtio_net: separate the logic of freeing xdp shinfo
  virtio_net: separate the logic of freeing the rest mergeable buf
  virtio_net: auto release xdp shinfo
  virtio_net: introduce receive_mergeable_xdp()
  virtio_net: merge: remove skip_xdp
  virtio_net: introduce receive_small_xdp()
  virtio_net: small: optimize code
  virtio_net: small: optimize code
  virtio_net: small: remove skip_xdp
  virtio_net: introduce receive_small_build_xdp
  virtio_net: introduce virtnet_build_skb()

 drivers/net/virtio_net.c | 659 +++++++++++++++++++++++----------------
 1 file changed, 386 insertions(+), 273 deletions(-)

-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 01/15] virtio_net: mergeable xdp: put old page immediately
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

In the xdp implementation of virtio-net mergeable, it always checks
whether two page is used and a page is selected to release. This is
complicated for the processing of action, and be careful.

In the entire process, we have such principles:
* If xdp_page is used (PASS, TX, Redirect), then we release the old
  page.
* If it is a drop case, we will release two. The old page obtained from
  buf is release inside err_xdp, and xdp_page needs be relased by us.

But in fact, when we allocate a new page, we can release the old page
immediately. Then just one is using, we just need to release the new
page for drop case. On the drop path, err_xdp will release the variable
"page", so we only need to let "page" point to the new xdp_page in
advance.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index e2560b6f7980..42435e762d72 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1245,6 +1245,9 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			if (!xdp_page)
 				goto err_xdp;
 			offset = VIRTIO_XDP_HEADROOM;
+
+			put_page(page);
+			page = xdp_page;
 		} else if (unlikely(headroom < virtnet_get_headroom(vi))) {
 			xdp_room = SKB_DATA_ALIGN(VIRTIO_XDP_HEADROOM +
 						  sizeof(struct skb_shared_info));
@@ -1259,11 +1262,12 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			       page_address(page) + offset, len);
 			frame_sz = PAGE_SIZE;
 			offset = VIRTIO_XDP_HEADROOM;
-		} else {
-			xdp_page = page;
+
+			put_page(page);
+			page = xdp_page;
 		}
 
-		data = page_address(xdp_page) + offset;
+		data = page_address(page) + offset;
 		err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
 						 &num_buf, &xdp_frags_truesz, stats);
 		if (unlikely(err))
@@ -1278,8 +1282,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			if (unlikely(!head_skb))
 				goto err_xdp_frags;
 
-			if (unlikely(xdp_page != page))
-				put_page(page);
 			rcu_read_unlock();
 			return head_skb;
 		case XDP_TX:
@@ -1297,8 +1299,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 				goto err_xdp_frags;
 			}
 			*xdp_xmit |= VIRTIO_XDP_TX;
-			if (unlikely(xdp_page != page))
-				put_page(page);
 			rcu_read_unlock();
 			goto xdp_xmit;
 		case XDP_REDIRECT:
@@ -1307,8 +1307,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			if (err)
 				goto err_xdp_frags;
 			*xdp_xmit |= VIRTIO_XDP_REDIR;
-			if (unlikely(xdp_page != page))
-				put_page(page);
 			rcu_read_unlock();
 			goto xdp_xmit;
 		default:
@@ -1321,9 +1319,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			goto err_xdp_frags;
 		}
 err_xdp_frags:
-		if (unlikely(xdp_page != page))
-			__free_pages(xdp_page, 0);
-
 		if (xdp_buff_has_frags(&xdp)) {
 			shinfo = xdp_get_shared_info_from_buff(&xdp);
 			for (i = 0; i < shinfo->nr_frags; i++) {
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 01/15] virtio_net: mergeable xdp: put old page immediately
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

In the xdp implementation of virtio-net mergeable, it always checks
whether two page is used and a page is selected to release. This is
complicated for the processing of action, and be careful.

In the entire process, we have such principles:
* If xdp_page is used (PASS, TX, Redirect), then we release the old
  page.
* If it is a drop case, we will release two. The old page obtained from
  buf is release inside err_xdp, and xdp_page needs be relased by us.

But in fact, when we allocate a new page, we can release the old page
immediately. Then just one is using, we just need to release the new
page for drop case. On the drop path, err_xdp will release the variable
"page", so we only need to let "page" point to the new xdp_page in
advance.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index e2560b6f7980..42435e762d72 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1245,6 +1245,9 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			if (!xdp_page)
 				goto err_xdp;
 			offset = VIRTIO_XDP_HEADROOM;
+
+			put_page(page);
+			page = xdp_page;
 		} else if (unlikely(headroom < virtnet_get_headroom(vi))) {
 			xdp_room = SKB_DATA_ALIGN(VIRTIO_XDP_HEADROOM +
 						  sizeof(struct skb_shared_info));
@@ -1259,11 +1262,12 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			       page_address(page) + offset, len);
 			frame_sz = PAGE_SIZE;
 			offset = VIRTIO_XDP_HEADROOM;
-		} else {
-			xdp_page = page;
+
+			put_page(page);
+			page = xdp_page;
 		}
 
-		data = page_address(xdp_page) + offset;
+		data = page_address(page) + offset;
 		err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
 						 &num_buf, &xdp_frags_truesz, stats);
 		if (unlikely(err))
@@ -1278,8 +1282,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			if (unlikely(!head_skb))
 				goto err_xdp_frags;
 
-			if (unlikely(xdp_page != page))
-				put_page(page);
 			rcu_read_unlock();
 			return head_skb;
 		case XDP_TX:
@@ -1297,8 +1299,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 				goto err_xdp_frags;
 			}
 			*xdp_xmit |= VIRTIO_XDP_TX;
-			if (unlikely(xdp_page != page))
-				put_page(page);
 			rcu_read_unlock();
 			goto xdp_xmit;
 		case XDP_REDIRECT:
@@ -1307,8 +1307,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			if (err)
 				goto err_xdp_frags;
 			*xdp_xmit |= VIRTIO_XDP_REDIR;
-			if (unlikely(xdp_page != page))
-				put_page(page);
 			rcu_read_unlock();
 			goto xdp_xmit;
 		default:
@@ -1321,9 +1319,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			goto err_xdp_frags;
 		}
 err_xdp_frags:
-		if (unlikely(xdp_page != page))
-			__free_pages(xdp_page, 0);
-
 		if (xdp_buff_has_frags(&xdp)) {
 			shinfo = xdp_get_shared_info_from_buff(&xdp);
 			for (i = 0; i < shinfo->nr_frags; i++) {
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 02/15] virtio_net: introduce mergeable_xdp_get_buf()
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

Separating the logic of preparation for xdp from receive_mergeable.

The purpose of this is to simplify the logic of execution of XDP.

The main logic here is that when headroom is insufficient, we need to
allocate a new page and calculate offset. It should be noted that if
there is new page, the variable page will refer to the new page.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 135 +++++++++++++++++++++++----------------
 1 file changed, 79 insertions(+), 56 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 42435e762d72..b8832b0cc215 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1162,6 +1162,81 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
 	return 0;
 }
 
+static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
+				   struct receive_queue *rq,
+				   struct bpf_prog *xdp_prog,
+				   void *ctx,
+				   unsigned int *frame_sz,
+				   int *num_buf,
+				   struct page **page,
+				   int offset,
+				   unsigned int *len,
+				   struct virtio_net_hdr_mrg_rxbuf *hdr)
+{
+	unsigned int truesize = mergeable_ctx_to_truesize(ctx);
+	unsigned int headroom = mergeable_ctx_to_headroom(ctx);
+	struct page *xdp_page;
+	unsigned int xdp_room;
+
+	/* Transient failure which in theory could occur if
+	 * in-flight packets from before XDP was enabled reach
+	 * the receive path after XDP is loaded.
+	 */
+	if (unlikely(hdr->hdr.gso_type))
+		return NULL;
+
+	/* Now XDP core assumes frag size is PAGE_SIZE, but buffers
+	 * with headroom may add hole in truesize, which
+	 * make their length exceed PAGE_SIZE. So we disabled the
+	 * hole mechanism for xdp. See add_recvbuf_mergeable().
+	 */
+	*frame_sz = truesize;
+
+	/* 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.
+	 * In fact, vq reset can be used here to help us clean up
+	 * the prefilled buffers, but many existing devices do not
+	 * 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))) {
+		/* 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))) {
+		xdp_room = SKB_DATA_ALIGN(VIRTIO_XDP_HEADROOM +
+					  sizeof(struct skb_shared_info));
+		if (*len + xdp_room > PAGE_SIZE)
+			return NULL;
+
+		xdp_page = alloc_page(GFP_ATOMIC);
+		if (!xdp_page)
+			return NULL;
+
+		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;
+}
+
 static struct sk_buff *receive_mergeable(struct net_device *dev,
 					 struct virtnet_info *vi,
 					 struct receive_queue *rq,
@@ -1181,7 +1256,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	unsigned int headroom = mergeable_ctx_to_headroom(ctx);
 	unsigned int tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
 	unsigned int room = SKB_DATA_ALIGN(headroom + tailroom);
-	unsigned int frame_sz, xdp_room;
+	unsigned int frame_sz;
 	int err;
 
 	head_skb = NULL;
@@ -1211,63 +1286,11 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		u32 act;
 		int i;
 
-		/* Transient failure which in theory could occur if
-		 * in-flight packets from before XDP was enabled reach
-		 * the receive path after XDP is loaded.
-		 */
-		if (unlikely(hdr->hdr.gso_type))
+		data = mergeable_xdp_get_buf(vi, rq, xdp_prog, ctx, &frame_sz,
+					     &num_buf, &page, offset, &len, hdr);
+		if (unlikely(!data))
 			goto err_xdp;
 
-		/* Now XDP core assumes frag size is PAGE_SIZE, but buffers
-		 * with headroom may add hole in truesize, which
-		 * make their length exceed PAGE_SIZE. So we disabled the
-		 * hole mechanism for xdp. See add_recvbuf_mergeable().
-		 */
-		frame_sz = truesize;
-
-		/* 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.
-		 * In fact, vq reset can be used here to help us clean up
-		 * the prefilled buffers, but many existing devices do not
-		 * 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))) {
-			/* 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)
-				goto err_xdp;
-			offset = VIRTIO_XDP_HEADROOM;
-
-			put_page(page);
-			page = xdp_page;
-		} else if (unlikely(headroom < virtnet_get_headroom(vi))) {
-			xdp_room = SKB_DATA_ALIGN(VIRTIO_XDP_HEADROOM +
-						  sizeof(struct skb_shared_info));
-			if (len + xdp_room > PAGE_SIZE)
-				goto err_xdp;
-
-			xdp_page = alloc_page(GFP_ATOMIC);
-			if (!xdp_page)
-				goto err_xdp;
-
-			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;
-		}
-
-		data = page_address(page) + offset;
 		err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
 						 &num_buf, &xdp_frags_truesz, stats);
 		if (unlikely(err))
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 02/15] virtio_net: introduce mergeable_xdp_get_buf()
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

Separating the logic of preparation for xdp from receive_mergeable.

The purpose of this is to simplify the logic of execution of XDP.

The main logic here is that when headroom is insufficient, we need to
allocate a new page and calculate offset. It should be noted that if
there is new page, the variable page will refer to the new page.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 135 +++++++++++++++++++++++----------------
 1 file changed, 79 insertions(+), 56 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 42435e762d72..b8832b0cc215 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1162,6 +1162,81 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
 	return 0;
 }
 
+static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
+				   struct receive_queue *rq,
+				   struct bpf_prog *xdp_prog,
+				   void *ctx,
+				   unsigned int *frame_sz,
+				   int *num_buf,
+				   struct page **page,
+				   int offset,
+				   unsigned int *len,
+				   struct virtio_net_hdr_mrg_rxbuf *hdr)
+{
+	unsigned int truesize = mergeable_ctx_to_truesize(ctx);
+	unsigned int headroom = mergeable_ctx_to_headroom(ctx);
+	struct page *xdp_page;
+	unsigned int xdp_room;
+
+	/* Transient failure which in theory could occur if
+	 * in-flight packets from before XDP was enabled reach
+	 * the receive path after XDP is loaded.
+	 */
+	if (unlikely(hdr->hdr.gso_type))
+		return NULL;
+
+	/* Now XDP core assumes frag size is PAGE_SIZE, but buffers
+	 * with headroom may add hole in truesize, which
+	 * make their length exceed PAGE_SIZE. So we disabled the
+	 * hole mechanism for xdp. See add_recvbuf_mergeable().
+	 */
+	*frame_sz = truesize;
+
+	/* 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.
+	 * In fact, vq reset can be used here to help us clean up
+	 * the prefilled buffers, but many existing devices do not
+	 * 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))) {
+		/* 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))) {
+		xdp_room = SKB_DATA_ALIGN(VIRTIO_XDP_HEADROOM +
+					  sizeof(struct skb_shared_info));
+		if (*len + xdp_room > PAGE_SIZE)
+			return NULL;
+
+		xdp_page = alloc_page(GFP_ATOMIC);
+		if (!xdp_page)
+			return NULL;
+
+		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;
+}
+
 static struct sk_buff *receive_mergeable(struct net_device *dev,
 					 struct virtnet_info *vi,
 					 struct receive_queue *rq,
@@ -1181,7 +1256,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	unsigned int headroom = mergeable_ctx_to_headroom(ctx);
 	unsigned int tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
 	unsigned int room = SKB_DATA_ALIGN(headroom + tailroom);
-	unsigned int frame_sz, xdp_room;
+	unsigned int frame_sz;
 	int err;
 
 	head_skb = NULL;
@@ -1211,63 +1286,11 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		u32 act;
 		int i;
 
-		/* Transient failure which in theory could occur if
-		 * in-flight packets from before XDP was enabled reach
-		 * the receive path after XDP is loaded.
-		 */
-		if (unlikely(hdr->hdr.gso_type))
+		data = mergeable_xdp_get_buf(vi, rq, xdp_prog, ctx, &frame_sz,
+					     &num_buf, &page, offset, &len, hdr);
+		if (unlikely(!data))
 			goto err_xdp;
 
-		/* Now XDP core assumes frag size is PAGE_SIZE, but buffers
-		 * with headroom may add hole in truesize, which
-		 * make their length exceed PAGE_SIZE. So we disabled the
-		 * hole mechanism for xdp. See add_recvbuf_mergeable().
-		 */
-		frame_sz = truesize;
-
-		/* 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.
-		 * In fact, vq reset can be used here to help us clean up
-		 * the prefilled buffers, but many existing devices do not
-		 * 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))) {
-			/* 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)
-				goto err_xdp;
-			offset = VIRTIO_XDP_HEADROOM;
-
-			put_page(page);
-			page = xdp_page;
-		} else if (unlikely(headroom < virtnet_get_headroom(vi))) {
-			xdp_room = SKB_DATA_ALIGN(VIRTIO_XDP_HEADROOM +
-						  sizeof(struct skb_shared_info));
-			if (len + xdp_room > PAGE_SIZE)
-				goto err_xdp;
-
-			xdp_page = alloc_page(GFP_ATOMIC);
-			if (!xdp_page)
-				goto err_xdp;
-
-			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;
-		}
-
-		data = page_address(page) + offset;
 		err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
 						 &num_buf, &xdp_frags_truesz, stats);
 		if (unlikely(err))
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 03/15] virtio_net: optimize mergeable_xdp_get_buf()
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

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>
---
 drivers/net/virtio_net.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index b8832b0cc215..6f66d73097b4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1192,6 +1192,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.
@@ -1200,22 +1205,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)
@@ -1227,14 +1225,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,
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 03/15] virtio_net: optimize mergeable_xdp_get_buf()
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

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>
---
 drivers/net/virtio_net.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index b8832b0cc215..6f66d73097b4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1192,6 +1192,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.
@@ -1200,22 +1205,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)
@@ -1227,14 +1225,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,
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 04/15] virtio_net: introduce virtnet_xdp_handler() to seprate the logic of run xdp
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

At present, we have two similar logic to perform the XDP prog.

Therefore, this patch separates the code of executing XDP, which is
conducive to later maintenance.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 118 +++++++++++++++++++--------------------
 1 file changed, 58 insertions(+), 60 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 6f66d73097b4..264945dd7a35 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -789,6 +789,60 @@ static int virtnet_xdp_xmit(struct net_device *dev,
 	return ret;
 }
 
+static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
+			       struct net_device *dev,
+			       unsigned int *xdp_xmit,
+			       struct virtnet_rq_stats *stats)
+{
+	struct xdp_frame *xdpf;
+	int err;
+	u32 act;
+
+	act = bpf_prog_run_xdp(xdp_prog, xdp);
+	stats->xdp_packets++;
+
+	switch (act) {
+	case XDP_PASS:
+		return act;
+
+	case XDP_TX:
+		stats->xdp_tx++;
+		xdpf = xdp_convert_buff_to_frame(xdp);
+		if (unlikely(!xdpf)) {
+			netdev_dbg(dev, "convert buff to frame failed for xdp\n");
+			return XDP_DROP;
+		}
+
+		err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
+		if (unlikely(!err)) {
+			xdp_return_frame_rx_napi(xdpf);
+		} else if (unlikely(err < 0)) {
+			trace_xdp_exception(dev, xdp_prog, act);
+			return XDP_DROP;
+		}
+		*xdp_xmit |= VIRTIO_XDP_TX;
+		return act;
+
+	case XDP_REDIRECT:
+		stats->xdp_redirects++;
+		err = xdp_do_redirect(dev, xdp, xdp_prog);
+		if (err)
+			return XDP_DROP;
+
+		*xdp_xmit |= VIRTIO_XDP_REDIR;
+		return act;
+
+	default:
+		bpf_warn_invalid_xdp_action(dev, xdp_prog, act);
+		fallthrough;
+	case XDP_ABORTED:
+		trace_xdp_exception(dev, xdp_prog, act);
+		fallthrough;
+	case XDP_DROP:
+		return XDP_DROP;
+	}
+}
+
 static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
 {
 	return vi->xdp_enabled ? VIRTIO_XDP_HEADROOM : 0;
@@ -876,7 +930,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	struct page *page = virt_to_head_page(buf);
 	unsigned int delta = 0;
 	struct page *xdp_page;
-	int err;
 	unsigned int metasize = 0;
 
 	len -= vi->hdr_len;
@@ -898,7 +951,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	xdp_prog = rcu_dereference(rq->xdp_prog);
 	if (xdp_prog) {
 		struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
-		struct xdp_frame *xdpf;
 		struct xdp_buff xdp;
 		void *orig_data;
 		u32 act;
@@ -931,8 +983,8 @@ static struct sk_buff *receive_small(struct net_device *dev,
 		xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
 				 xdp_headroom, len, true);
 		orig_data = xdp.data;
-		act = bpf_prog_run_xdp(xdp_prog, &xdp);
-		stats->xdp_packets++;
+
+		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
 
 		switch (act) {
 		case XDP_PASS:
@@ -942,35 +994,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
 			metasize = xdp.data - xdp.data_meta;
 			break;
 		case XDP_TX:
-			stats->xdp_tx++;
-			xdpf = xdp_convert_buff_to_frame(&xdp);
-			if (unlikely(!xdpf))
-				goto err_xdp;
-			err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
-			if (unlikely(!err)) {
-				xdp_return_frame_rx_napi(xdpf);
-			} else if (unlikely(err < 0)) {
-				trace_xdp_exception(vi->dev, xdp_prog, act);
-				goto err_xdp;
-			}
-			*xdp_xmit |= VIRTIO_XDP_TX;
-			rcu_read_unlock();
-			goto xdp_xmit;
 		case XDP_REDIRECT:
-			stats->xdp_redirects++;
-			err = xdp_do_redirect(dev, &xdp, xdp_prog);
-			if (err)
-				goto err_xdp;
-			*xdp_xmit |= VIRTIO_XDP_REDIR;
 			rcu_read_unlock();
 			goto xdp_xmit;
 		default:
-			bpf_warn_invalid_xdp_action(vi->dev, xdp_prog, act);
-			fallthrough;
-		case XDP_ABORTED:
-			trace_xdp_exception(vi->dev, xdp_prog, act);
-			goto err_xdp;
-		case XDP_DROP:
 			goto err_xdp;
 		}
 	}
@@ -1278,7 +1305,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	if (xdp_prog) {
 		unsigned int xdp_frags_truesz = 0;
 		struct skb_shared_info *shinfo;
-		struct xdp_frame *xdpf;
 		struct page *xdp_page;
 		struct xdp_buff xdp;
 		void *data;
@@ -1295,8 +1321,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		if (unlikely(err))
 			goto err_xdp_frags;
 
-		act = bpf_prog_run_xdp(xdp_prog, &xdp);
-		stats->xdp_packets++;
+		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
 
 		switch (act) {
 		case XDP_PASS:
@@ -1307,38 +1332,11 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			rcu_read_unlock();
 			return head_skb;
 		case XDP_TX:
-			stats->xdp_tx++;
-			xdpf = xdp_convert_buff_to_frame(&xdp);
-			if (unlikely(!xdpf)) {
-				netdev_dbg(dev, "convert buff to frame failed for xdp\n");
-				goto err_xdp_frags;
-			}
-			err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
-			if (unlikely(!err)) {
-				xdp_return_frame_rx_napi(xdpf);
-			} else if (unlikely(err < 0)) {
-				trace_xdp_exception(vi->dev, xdp_prog, act);
-				goto err_xdp_frags;
-			}
-			*xdp_xmit |= VIRTIO_XDP_TX;
-			rcu_read_unlock();
-			goto xdp_xmit;
 		case XDP_REDIRECT:
-			stats->xdp_redirects++;
-			err = xdp_do_redirect(dev, &xdp, xdp_prog);
-			if (err)
-				goto err_xdp_frags;
-			*xdp_xmit |= VIRTIO_XDP_REDIR;
 			rcu_read_unlock();
 			goto xdp_xmit;
 		default:
-			bpf_warn_invalid_xdp_action(vi->dev, xdp_prog, act);
-			fallthrough;
-		case XDP_ABORTED:
-			trace_xdp_exception(vi->dev, xdp_prog, act);
-			fallthrough;
-		case XDP_DROP:
-			goto err_xdp_frags;
+			break;
 		}
 err_xdp_frags:
 		if (xdp_buff_has_frags(&xdp)) {
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 04/15] virtio_net: introduce virtnet_xdp_handler() to seprate the logic of run xdp
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

At present, we have two similar logic to perform the XDP prog.

Therefore, this patch separates the code of executing XDP, which is
conducive to later maintenance.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 118 +++++++++++++++++++--------------------
 1 file changed, 58 insertions(+), 60 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 6f66d73097b4..264945dd7a35 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -789,6 +789,60 @@ static int virtnet_xdp_xmit(struct net_device *dev,
 	return ret;
 }
 
+static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
+			       struct net_device *dev,
+			       unsigned int *xdp_xmit,
+			       struct virtnet_rq_stats *stats)
+{
+	struct xdp_frame *xdpf;
+	int err;
+	u32 act;
+
+	act = bpf_prog_run_xdp(xdp_prog, xdp);
+	stats->xdp_packets++;
+
+	switch (act) {
+	case XDP_PASS:
+		return act;
+
+	case XDP_TX:
+		stats->xdp_tx++;
+		xdpf = xdp_convert_buff_to_frame(xdp);
+		if (unlikely(!xdpf)) {
+			netdev_dbg(dev, "convert buff to frame failed for xdp\n");
+			return XDP_DROP;
+		}
+
+		err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
+		if (unlikely(!err)) {
+			xdp_return_frame_rx_napi(xdpf);
+		} else if (unlikely(err < 0)) {
+			trace_xdp_exception(dev, xdp_prog, act);
+			return XDP_DROP;
+		}
+		*xdp_xmit |= VIRTIO_XDP_TX;
+		return act;
+
+	case XDP_REDIRECT:
+		stats->xdp_redirects++;
+		err = xdp_do_redirect(dev, xdp, xdp_prog);
+		if (err)
+			return XDP_DROP;
+
+		*xdp_xmit |= VIRTIO_XDP_REDIR;
+		return act;
+
+	default:
+		bpf_warn_invalid_xdp_action(dev, xdp_prog, act);
+		fallthrough;
+	case XDP_ABORTED:
+		trace_xdp_exception(dev, xdp_prog, act);
+		fallthrough;
+	case XDP_DROP:
+		return XDP_DROP;
+	}
+}
+
 static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
 {
 	return vi->xdp_enabled ? VIRTIO_XDP_HEADROOM : 0;
@@ -876,7 +930,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	struct page *page = virt_to_head_page(buf);
 	unsigned int delta = 0;
 	struct page *xdp_page;
-	int err;
 	unsigned int metasize = 0;
 
 	len -= vi->hdr_len;
@@ -898,7 +951,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	xdp_prog = rcu_dereference(rq->xdp_prog);
 	if (xdp_prog) {
 		struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
-		struct xdp_frame *xdpf;
 		struct xdp_buff xdp;
 		void *orig_data;
 		u32 act;
@@ -931,8 +983,8 @@ static struct sk_buff *receive_small(struct net_device *dev,
 		xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
 				 xdp_headroom, len, true);
 		orig_data = xdp.data;
-		act = bpf_prog_run_xdp(xdp_prog, &xdp);
-		stats->xdp_packets++;
+
+		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
 
 		switch (act) {
 		case XDP_PASS:
@@ -942,35 +994,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
 			metasize = xdp.data - xdp.data_meta;
 			break;
 		case XDP_TX:
-			stats->xdp_tx++;
-			xdpf = xdp_convert_buff_to_frame(&xdp);
-			if (unlikely(!xdpf))
-				goto err_xdp;
-			err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
-			if (unlikely(!err)) {
-				xdp_return_frame_rx_napi(xdpf);
-			} else if (unlikely(err < 0)) {
-				trace_xdp_exception(vi->dev, xdp_prog, act);
-				goto err_xdp;
-			}
-			*xdp_xmit |= VIRTIO_XDP_TX;
-			rcu_read_unlock();
-			goto xdp_xmit;
 		case XDP_REDIRECT:
-			stats->xdp_redirects++;
-			err = xdp_do_redirect(dev, &xdp, xdp_prog);
-			if (err)
-				goto err_xdp;
-			*xdp_xmit |= VIRTIO_XDP_REDIR;
 			rcu_read_unlock();
 			goto xdp_xmit;
 		default:
-			bpf_warn_invalid_xdp_action(vi->dev, xdp_prog, act);
-			fallthrough;
-		case XDP_ABORTED:
-			trace_xdp_exception(vi->dev, xdp_prog, act);
-			goto err_xdp;
-		case XDP_DROP:
 			goto err_xdp;
 		}
 	}
@@ -1278,7 +1305,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	if (xdp_prog) {
 		unsigned int xdp_frags_truesz = 0;
 		struct skb_shared_info *shinfo;
-		struct xdp_frame *xdpf;
 		struct page *xdp_page;
 		struct xdp_buff xdp;
 		void *data;
@@ -1295,8 +1321,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		if (unlikely(err))
 			goto err_xdp_frags;
 
-		act = bpf_prog_run_xdp(xdp_prog, &xdp);
-		stats->xdp_packets++;
+		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
 
 		switch (act) {
 		case XDP_PASS:
@@ -1307,38 +1332,11 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			rcu_read_unlock();
 			return head_skb;
 		case XDP_TX:
-			stats->xdp_tx++;
-			xdpf = xdp_convert_buff_to_frame(&xdp);
-			if (unlikely(!xdpf)) {
-				netdev_dbg(dev, "convert buff to frame failed for xdp\n");
-				goto err_xdp_frags;
-			}
-			err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
-			if (unlikely(!err)) {
-				xdp_return_frame_rx_napi(xdpf);
-			} else if (unlikely(err < 0)) {
-				trace_xdp_exception(vi->dev, xdp_prog, act);
-				goto err_xdp_frags;
-			}
-			*xdp_xmit |= VIRTIO_XDP_TX;
-			rcu_read_unlock();
-			goto xdp_xmit;
 		case XDP_REDIRECT:
-			stats->xdp_redirects++;
-			err = xdp_do_redirect(dev, &xdp, xdp_prog);
-			if (err)
-				goto err_xdp_frags;
-			*xdp_xmit |= VIRTIO_XDP_REDIR;
 			rcu_read_unlock();
 			goto xdp_xmit;
 		default:
-			bpf_warn_invalid_xdp_action(vi->dev, xdp_prog, act);
-			fallthrough;
-		case XDP_ABORTED:
-			trace_xdp_exception(vi->dev, xdp_prog, act);
-			fallthrough;
-		case XDP_DROP:
-			goto err_xdp_frags;
+			break;
 		}
 err_xdp_frags:
 		if (xdp_buff_has_frags(&xdp)) {
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 05/15] virtio_net: separate the logic of freeing xdp shinfo
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

This patch introduce a new function that releases the
xdp shinfo. The subsequent patch will reuse this function.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 264945dd7a35..b4eb083ebf55 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -789,6 +789,21 @@ static int virtnet_xdp_xmit(struct net_device *dev,
 	return ret;
 }
 
+static void put_xdp_frags(struct xdp_buff *xdp)
+{
+	struct skb_shared_info *shinfo;
+	struct page *xdp_page;
+	int i;
+
+	if (xdp_buff_has_frags(xdp)) {
+		shinfo = xdp_get_shared_info_from_buff(xdp);
+		for (i = 0; i < shinfo->nr_frags; i++) {
+			xdp_page = skb_frag_page(&shinfo->frags[i]);
+			put_page(xdp_page);
+		}
+	}
+}
+
 static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 			       struct net_device *dev,
 			       unsigned int *xdp_xmit,
@@ -1304,12 +1319,9 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	xdp_prog = rcu_dereference(rq->xdp_prog);
 	if (xdp_prog) {
 		unsigned int xdp_frags_truesz = 0;
-		struct skb_shared_info *shinfo;
-		struct page *xdp_page;
 		struct xdp_buff xdp;
 		void *data;
 		u32 act;
-		int i;
 
 		data = mergeable_xdp_get_buf(vi, rq, xdp_prog, ctx, &frame_sz,
 					     &num_buf, &page, offset, &len, hdr);
@@ -1339,14 +1351,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			break;
 		}
 err_xdp_frags:
-		if (xdp_buff_has_frags(&xdp)) {
-			shinfo = xdp_get_shared_info_from_buff(&xdp);
-			for (i = 0; i < shinfo->nr_frags; i++) {
-				xdp_page = skb_frag_page(&shinfo->frags[i]);
-				put_page(xdp_page);
-			}
-		}
-
+		put_xdp_frags(&xdp);
 		goto err_xdp;
 	}
 	rcu_read_unlock();
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 05/15] virtio_net: separate the logic of freeing xdp shinfo
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

This patch introduce a new function that releases the
xdp shinfo. The subsequent patch will reuse this function.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 264945dd7a35..b4eb083ebf55 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -789,6 +789,21 @@ static int virtnet_xdp_xmit(struct net_device *dev,
 	return ret;
 }
 
+static void put_xdp_frags(struct xdp_buff *xdp)
+{
+	struct skb_shared_info *shinfo;
+	struct page *xdp_page;
+	int i;
+
+	if (xdp_buff_has_frags(xdp)) {
+		shinfo = xdp_get_shared_info_from_buff(xdp);
+		for (i = 0; i < shinfo->nr_frags; i++) {
+			xdp_page = skb_frag_page(&shinfo->frags[i]);
+			put_page(xdp_page);
+		}
+	}
+}
+
 static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 			       struct net_device *dev,
 			       unsigned int *xdp_xmit,
@@ -1304,12 +1319,9 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	xdp_prog = rcu_dereference(rq->xdp_prog);
 	if (xdp_prog) {
 		unsigned int xdp_frags_truesz = 0;
-		struct skb_shared_info *shinfo;
-		struct page *xdp_page;
 		struct xdp_buff xdp;
 		void *data;
 		u32 act;
-		int i;
 
 		data = mergeable_xdp_get_buf(vi, rq, xdp_prog, ctx, &frame_sz,
 					     &num_buf, &page, offset, &len, hdr);
@@ -1339,14 +1351,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			break;
 		}
 err_xdp_frags:
-		if (xdp_buff_has_frags(&xdp)) {
-			shinfo = xdp_get_shared_info_from_buff(&xdp);
-			for (i = 0; i < shinfo->nr_frags; i++) {
-				xdp_page = skb_frag_page(&shinfo->frags[i]);
-				put_page(xdp_page);
-			}
-		}
-
+		put_xdp_frags(&xdp);
 		goto err_xdp;
 	}
 	rcu_read_unlock();
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 06/15] virtio_net: separate the logic of freeing the rest mergeable buf
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

This patch introduce a new function that frees the rest mergeable buf.
The subsequent patch will reuse this function.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index b4eb083ebf55..5f37a1cef61e 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1067,6 +1067,28 @@ static struct sk_buff *receive_big(struct net_device *dev,
 	return NULL;
 }
 
+static void mergeable_buf_free(struct receive_queue *rq, int num_buf,
+			       struct net_device *dev,
+			       struct virtnet_rq_stats *stats)
+{
+	struct page *page;
+	void *buf;
+	int len;
+
+	while (num_buf-- > 1) {
+		buf = virtqueue_get_buf(rq->vq, &len);
+		if (unlikely(!buf)) {
+			pr_debug("%s: rx error: %d buffers missing\n",
+				 dev->name, num_buf);
+			dev->stats.rx_length_errors++;
+			break;
+		}
+		stats->bytes += len;
+		page = virt_to_head_page(buf);
+		put_page(page);
+	}
+}
+
 /* Why not use xdp_build_skb_from_frame() ?
  * XDP core assumes that xdp frags are PAGE_SIZE in length, while in
  * virtio-net there are 2 points that do not match its requirements:
@@ -1427,18 +1449,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	stats->xdp_drops++;
 err_skb:
 	put_page(page);
-	while (num_buf-- > 1) {
-		buf = virtqueue_get_buf(rq->vq, &len);
-		if (unlikely(!buf)) {
-			pr_debug("%s: rx error: %d buffers missing\n",
-				 dev->name, num_buf);
-			dev->stats.rx_length_errors++;
-			break;
-		}
-		stats->bytes += len;
-		page = virt_to_head_page(buf);
-		put_page(page);
-	}
+	mergeable_buf_free(rq, num_buf, dev, stats);
+
 err_buf:
 	stats->drops++;
 	dev_kfree_skb(head_skb);
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 06/15] virtio_net: separate the logic of freeing the rest mergeable buf
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

This patch introduce a new function that frees the rest mergeable buf.
The subsequent patch will reuse this function.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index b4eb083ebf55..5f37a1cef61e 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1067,6 +1067,28 @@ static struct sk_buff *receive_big(struct net_device *dev,
 	return NULL;
 }
 
+static void mergeable_buf_free(struct receive_queue *rq, int num_buf,
+			       struct net_device *dev,
+			       struct virtnet_rq_stats *stats)
+{
+	struct page *page;
+	void *buf;
+	int len;
+
+	while (num_buf-- > 1) {
+		buf = virtqueue_get_buf(rq->vq, &len);
+		if (unlikely(!buf)) {
+			pr_debug("%s: rx error: %d buffers missing\n",
+				 dev->name, num_buf);
+			dev->stats.rx_length_errors++;
+			break;
+		}
+		stats->bytes += len;
+		page = virt_to_head_page(buf);
+		put_page(page);
+	}
+}
+
 /* Why not use xdp_build_skb_from_frame() ?
  * XDP core assumes that xdp frags are PAGE_SIZE in length, while in
  * virtio-net there are 2 points that do not match its requirements:
@@ -1427,18 +1449,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	stats->xdp_drops++;
 err_skb:
 	put_page(page);
-	while (num_buf-- > 1) {
-		buf = virtqueue_get_buf(rq->vq, &len);
-		if (unlikely(!buf)) {
-			pr_debug("%s: rx error: %d buffers missing\n",
-				 dev->name, num_buf);
-			dev->stats.rx_length_errors++;
-			break;
-		}
-		stats->bytes += len;
-		page = virt_to_head_page(buf);
-		put_page(page);
-	}
+	mergeable_buf_free(rq, num_buf, dev, stats);
+
 err_buf:
 	stats->drops++;
 	dev_kfree_skb(head_skb);
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 07/15] virtio_net: auto release xdp shinfo
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

virtnet_build_xdp_buff_mrg() and virtnet_xdp_handler() auto
release xdp shinfo then the caller no need to careful the xdp shinfo.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 5f37a1cef61e..c6bf425e8844 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -825,7 +825,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 		xdpf = xdp_convert_buff_to_frame(xdp);
 		if (unlikely(!xdpf)) {
 			netdev_dbg(dev, "convert buff to frame failed for xdp\n");
-			return XDP_DROP;
+			goto drop;
 		}
 
 		err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
@@ -833,7 +833,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 			xdp_return_frame_rx_napi(xdpf);
 		} else if (unlikely(err < 0)) {
 			trace_xdp_exception(dev, xdp_prog, act);
-			return XDP_DROP;
+			goto drop;
 		}
 		*xdp_xmit |= VIRTIO_XDP_TX;
 		return act;
@@ -842,7 +842,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 		stats->xdp_redirects++;
 		err = xdp_do_redirect(dev, xdp, xdp_prog);
 		if (err)
-			return XDP_DROP;
+			goto drop;
 
 		*xdp_xmit |= VIRTIO_XDP_REDIR;
 		return act;
@@ -854,8 +854,12 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 		trace_xdp_exception(dev, xdp_prog, act);
 		fallthrough;
 	case XDP_DROP:
-		return XDP_DROP;
+		break;
 	}
+
+drop:
+	put_xdp_frags(xdp);
+	return XDP_DROP;
 }
 
 static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
@@ -1190,7 +1194,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
 				 dev->name, *num_buf,
 				 virtio16_to_cpu(vi->vdev, hdr->num_buffers));
 			dev->stats.rx_length_errors++;
-			return -EINVAL;
+			goto err;
 		}
 
 		stats->bytes += len;
@@ -1209,7 +1213,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
 			pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
 				 dev->name, len, (unsigned long)(truesize - room));
 			dev->stats.rx_length_errors++;
-			return -EINVAL;
+			goto err;
 		}
 
 		frag = &shinfo->frags[shinfo->nr_frags++];
@@ -1224,6 +1228,10 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
 
 	*xdp_frags_truesize = xdp_frags_truesz;
 	return 0;
+
+err:
+	put_xdp_frags(xdp);
+	return -EINVAL;
 }
 
 static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
@@ -1353,7 +1361,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
 						 &num_buf, &xdp_frags_truesz, stats);
 		if (unlikely(err))
-			goto err_xdp_frags;
+			goto err_xdp;
 
 		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
 
@@ -1361,7 +1369,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		case XDP_PASS:
 			head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
 			if (unlikely(!head_skb))
-				goto err_xdp_frags;
+				goto err_xdp;
 
 			rcu_read_unlock();
 			return head_skb;
@@ -1370,11 +1378,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			rcu_read_unlock();
 			goto xdp_xmit;
 		default:
-			break;
+			goto err_xdp;
 		}
-err_xdp_frags:
-		put_xdp_frags(&xdp);
-		goto err_xdp;
 	}
 	rcu_read_unlock();
 
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 07/15] virtio_net: auto release xdp shinfo
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

virtnet_build_xdp_buff_mrg() and virtnet_xdp_handler() auto
release xdp shinfo then the caller no need to careful the xdp shinfo.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 5f37a1cef61e..c6bf425e8844 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -825,7 +825,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 		xdpf = xdp_convert_buff_to_frame(xdp);
 		if (unlikely(!xdpf)) {
 			netdev_dbg(dev, "convert buff to frame failed for xdp\n");
-			return XDP_DROP;
+			goto drop;
 		}
 
 		err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
@@ -833,7 +833,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 			xdp_return_frame_rx_napi(xdpf);
 		} else if (unlikely(err < 0)) {
 			trace_xdp_exception(dev, xdp_prog, act);
-			return XDP_DROP;
+			goto drop;
 		}
 		*xdp_xmit |= VIRTIO_XDP_TX;
 		return act;
@@ -842,7 +842,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 		stats->xdp_redirects++;
 		err = xdp_do_redirect(dev, xdp, xdp_prog);
 		if (err)
-			return XDP_DROP;
+			goto drop;
 
 		*xdp_xmit |= VIRTIO_XDP_REDIR;
 		return act;
@@ -854,8 +854,12 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
 		trace_xdp_exception(dev, xdp_prog, act);
 		fallthrough;
 	case XDP_DROP:
-		return XDP_DROP;
+		break;
 	}
+
+drop:
+	put_xdp_frags(xdp);
+	return XDP_DROP;
 }
 
 static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
@@ -1190,7 +1194,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
 				 dev->name, *num_buf,
 				 virtio16_to_cpu(vi->vdev, hdr->num_buffers));
 			dev->stats.rx_length_errors++;
-			return -EINVAL;
+			goto err;
 		}
 
 		stats->bytes += len;
@@ -1209,7 +1213,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
 			pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
 				 dev->name, len, (unsigned long)(truesize - room));
 			dev->stats.rx_length_errors++;
-			return -EINVAL;
+			goto err;
 		}
 
 		frag = &shinfo->frags[shinfo->nr_frags++];
@@ -1224,6 +1228,10 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
 
 	*xdp_frags_truesize = xdp_frags_truesz;
 	return 0;
+
+err:
+	put_xdp_frags(xdp);
+	return -EINVAL;
 }
 
 static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
@@ -1353,7 +1361,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
 						 &num_buf, &xdp_frags_truesz, stats);
 		if (unlikely(err))
-			goto err_xdp_frags;
+			goto err_xdp;
 
 		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
 
@@ -1361,7 +1369,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		case XDP_PASS:
 			head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
 			if (unlikely(!head_skb))
-				goto err_xdp_frags;
+				goto err_xdp;
 
 			rcu_read_unlock();
 			return head_skb;
@@ -1370,11 +1378,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 			rcu_read_unlock();
 			goto xdp_xmit;
 		default:
-			break;
+			goto err_xdp;
 		}
-err_xdp_frags:
-		put_xdp_frags(&xdp);
-		goto err_xdp;
 	}
 	rcu_read_unlock();
 
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 08/15] virtio_net: introduce receive_mergeable_xdp()
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

The purpose of this patch is to simplify the receive_mergeable().
Separate all the logic of XDP into a function.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 100 ++++++++++++++++++++++++---------------
 1 file changed, 62 insertions(+), 38 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c6bf425e8844..da15f4e75a85 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1308,6 +1308,64 @@ static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
 	return page_address(*page) + VIRTIO_XDP_HEADROOM;
 }
 
+static struct sk_buff *receive_mergeable_xdp(struct net_device *dev,
+					     struct virtnet_info *vi,
+					     struct receive_queue *rq,
+					     struct bpf_prog *xdp_prog,
+					     void *buf,
+					     void *ctx,
+					     unsigned int len,
+					     unsigned int *xdp_xmit,
+					     struct virtnet_rq_stats *stats)
+{
+	struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
+	int num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers);
+	struct page *page = virt_to_head_page(buf);
+	int offset = buf - page_address(page);
+	unsigned int xdp_frags_truesz = 0;
+	struct sk_buff *head_skb;
+	unsigned int frame_sz;
+	struct xdp_buff xdp;
+	void *data;
+	u32 act;
+	int err;
+
+	data = mergeable_xdp_get_buf(vi, rq, xdp_prog, ctx, &frame_sz, &num_buf, &page,
+				     offset, &len, hdr);
+	if (unlikely(!data))
+		goto err_xdp;
+
+	err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
+					 &num_buf, &xdp_frags_truesz, stats);
+	if (unlikely(err))
+		goto err_xdp;
+
+	act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
+
+	switch (act) {
+	case XDP_PASS:
+		head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
+		if (unlikely(!head_skb))
+			goto err_xdp;
+		return head_skb;
+
+	case XDP_TX:
+	case XDP_REDIRECT:
+		return NULL;
+
+	default:
+		break;
+	}
+
+err_xdp:
+	put_page(page);
+	mergeable_buf_free(rq, num_buf, dev, stats);
+
+	stats->xdp_drops++;
+	stats->drops++;
+	return NULL;
+}
+
 static struct sk_buff *receive_mergeable(struct net_device *dev,
 					 struct virtnet_info *vi,
 					 struct receive_queue *rq,
@@ -1327,8 +1385,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	unsigned int headroom = mergeable_ctx_to_headroom(ctx);
 	unsigned int tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
 	unsigned int room = SKB_DATA_ALIGN(headroom + tailroom);
-	unsigned int frame_sz;
-	int err;
 
 	head_skb = NULL;
 	stats->bytes += len - vi->hdr_len;
@@ -1348,38 +1404,10 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	rcu_read_lock();
 	xdp_prog = rcu_dereference(rq->xdp_prog);
 	if (xdp_prog) {
-		unsigned int xdp_frags_truesz = 0;
-		struct xdp_buff xdp;
-		void *data;
-		u32 act;
-
-		data = mergeable_xdp_get_buf(vi, rq, xdp_prog, ctx, &frame_sz,
-					     &num_buf, &page, offset, &len, hdr);
-		if (unlikely(!data))
-			goto err_xdp;
-
-		err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
-						 &num_buf, &xdp_frags_truesz, stats);
-		if (unlikely(err))
-			goto err_xdp;
-
-		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
-
-		switch (act) {
-		case XDP_PASS:
-			head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
-			if (unlikely(!head_skb))
-				goto err_xdp;
-
-			rcu_read_unlock();
-			return head_skb;
-		case XDP_TX:
-		case XDP_REDIRECT:
-			rcu_read_unlock();
-			goto xdp_xmit;
-		default:
-			goto err_xdp;
-		}
+		head_skb = receive_mergeable_xdp(dev, vi, rq, xdp_prog, buf, ctx,
+						 len, xdp_xmit, stats);
+		rcu_read_unlock();
+		return head_skb;
 	}
 	rcu_read_unlock();
 
@@ -1449,9 +1477,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	ewma_pkt_len_add(&rq->mrg_avg_pkt_len, head_skb->len);
 	return head_skb;
 
-err_xdp:
-	rcu_read_unlock();
-	stats->xdp_drops++;
 err_skb:
 	put_page(page);
 	mergeable_buf_free(rq, num_buf, dev, stats);
@@ -1459,7 +1484,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 err_buf:
 	stats->drops++;
 	dev_kfree_skb(head_skb);
-xdp_xmit:
 	return NULL;
 }
 
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 08/15] virtio_net: introduce receive_mergeable_xdp()
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

The purpose of this patch is to simplify the receive_mergeable().
Separate all the logic of XDP into a function.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 100 ++++++++++++++++++++++++---------------
 1 file changed, 62 insertions(+), 38 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c6bf425e8844..da15f4e75a85 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1308,6 +1308,64 @@ static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
 	return page_address(*page) + VIRTIO_XDP_HEADROOM;
 }
 
+static struct sk_buff *receive_mergeable_xdp(struct net_device *dev,
+					     struct virtnet_info *vi,
+					     struct receive_queue *rq,
+					     struct bpf_prog *xdp_prog,
+					     void *buf,
+					     void *ctx,
+					     unsigned int len,
+					     unsigned int *xdp_xmit,
+					     struct virtnet_rq_stats *stats)
+{
+	struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
+	int num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers);
+	struct page *page = virt_to_head_page(buf);
+	int offset = buf - page_address(page);
+	unsigned int xdp_frags_truesz = 0;
+	struct sk_buff *head_skb;
+	unsigned int frame_sz;
+	struct xdp_buff xdp;
+	void *data;
+	u32 act;
+	int err;
+
+	data = mergeable_xdp_get_buf(vi, rq, xdp_prog, ctx, &frame_sz, &num_buf, &page,
+				     offset, &len, hdr);
+	if (unlikely(!data))
+		goto err_xdp;
+
+	err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
+					 &num_buf, &xdp_frags_truesz, stats);
+	if (unlikely(err))
+		goto err_xdp;
+
+	act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
+
+	switch (act) {
+	case XDP_PASS:
+		head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
+		if (unlikely(!head_skb))
+			goto err_xdp;
+		return head_skb;
+
+	case XDP_TX:
+	case XDP_REDIRECT:
+		return NULL;
+
+	default:
+		break;
+	}
+
+err_xdp:
+	put_page(page);
+	mergeable_buf_free(rq, num_buf, dev, stats);
+
+	stats->xdp_drops++;
+	stats->drops++;
+	return NULL;
+}
+
 static struct sk_buff *receive_mergeable(struct net_device *dev,
 					 struct virtnet_info *vi,
 					 struct receive_queue *rq,
@@ -1327,8 +1385,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	unsigned int headroom = mergeable_ctx_to_headroom(ctx);
 	unsigned int tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
 	unsigned int room = SKB_DATA_ALIGN(headroom + tailroom);
-	unsigned int frame_sz;
-	int err;
 
 	head_skb = NULL;
 	stats->bytes += len - vi->hdr_len;
@@ -1348,38 +1404,10 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	rcu_read_lock();
 	xdp_prog = rcu_dereference(rq->xdp_prog);
 	if (xdp_prog) {
-		unsigned int xdp_frags_truesz = 0;
-		struct xdp_buff xdp;
-		void *data;
-		u32 act;
-
-		data = mergeable_xdp_get_buf(vi, rq, xdp_prog, ctx, &frame_sz,
-					     &num_buf, &page, offset, &len, hdr);
-		if (unlikely(!data))
-			goto err_xdp;
-
-		err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
-						 &num_buf, &xdp_frags_truesz, stats);
-		if (unlikely(err))
-			goto err_xdp;
-
-		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
-
-		switch (act) {
-		case XDP_PASS:
-			head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
-			if (unlikely(!head_skb))
-				goto err_xdp;
-
-			rcu_read_unlock();
-			return head_skb;
-		case XDP_TX:
-		case XDP_REDIRECT:
-			rcu_read_unlock();
-			goto xdp_xmit;
-		default:
-			goto err_xdp;
-		}
+		head_skb = receive_mergeable_xdp(dev, vi, rq, xdp_prog, buf, ctx,
+						 len, xdp_xmit, stats);
+		rcu_read_unlock();
+		return head_skb;
 	}
 	rcu_read_unlock();
 
@@ -1449,9 +1477,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	ewma_pkt_len_add(&rq->mrg_avg_pkt_len, head_skb->len);
 	return head_skb;
 
-err_xdp:
-	rcu_read_unlock();
-	stats->xdp_drops++;
 err_skb:
 	put_page(page);
 	mergeable_buf_free(rq, num_buf, dev, stats);
@@ -1459,7 +1484,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 err_buf:
 	stats->drops++;
 	dev_kfree_skb(head_skb);
-xdp_xmit:
 	return NULL;
 }
 
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 09/15] virtio_net: merge: remove skip_xdp
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

Now, the logic of merge xdp process is simple, we can remove the
skip_xdp.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index da15f4e75a85..de5a579e8603 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1380,7 +1380,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	struct page *page = virt_to_head_page(buf);
 	int offset = buf - page_address(page);
 	struct sk_buff *head_skb, *curr_skb;
-	struct bpf_prog *xdp_prog;
 	unsigned int truesize = mergeable_ctx_to_truesize(ctx);
 	unsigned int headroom = mergeable_ctx_to_headroom(ctx);
 	unsigned int tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
@@ -1396,22 +1395,20 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		goto err_skb;
 	}
 
-	if (likely(!vi->xdp_enabled)) {
-		xdp_prog = NULL;
-		goto skip_xdp;
-	}
+	if (unlikely(vi->xdp_enabled)) {
+		struct bpf_prog *xdp_prog;
 
-	rcu_read_lock();
-	xdp_prog = rcu_dereference(rq->xdp_prog);
-	if (xdp_prog) {
-		head_skb = receive_mergeable_xdp(dev, vi, rq, xdp_prog, buf, ctx,
-						 len, xdp_xmit, stats);
+		rcu_read_lock();
+		xdp_prog = rcu_dereference(rq->xdp_prog);
+		if (xdp_prog) {
+			head_skb = receive_mergeable_xdp(dev, vi, rq, xdp_prog, buf, ctx,
+							 len, xdp_xmit, stats);
+			rcu_read_unlock();
+			return head_skb;
+		}
 		rcu_read_unlock();
-		return head_skb;
 	}
-	rcu_read_unlock();
 
-skip_xdp:
 	head_skb = page_to_skb(vi, rq, page, offset, len, truesize, headroom);
 	curr_skb = head_skb;
 
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 09/15] virtio_net: merge: remove skip_xdp
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

Now, the logic of merge xdp process is simple, we can remove the
skip_xdp.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index da15f4e75a85..de5a579e8603 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1380,7 +1380,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 	struct page *page = virt_to_head_page(buf);
 	int offset = buf - page_address(page);
 	struct sk_buff *head_skb, *curr_skb;
-	struct bpf_prog *xdp_prog;
 	unsigned int truesize = mergeable_ctx_to_truesize(ctx);
 	unsigned int headroom = mergeable_ctx_to_headroom(ctx);
 	unsigned int tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
@@ -1396,22 +1395,20 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
 		goto err_skb;
 	}
 
-	if (likely(!vi->xdp_enabled)) {
-		xdp_prog = NULL;
-		goto skip_xdp;
-	}
+	if (unlikely(vi->xdp_enabled)) {
+		struct bpf_prog *xdp_prog;
 
-	rcu_read_lock();
-	xdp_prog = rcu_dereference(rq->xdp_prog);
-	if (xdp_prog) {
-		head_skb = receive_mergeable_xdp(dev, vi, rq, xdp_prog, buf, ctx,
-						 len, xdp_xmit, stats);
+		rcu_read_lock();
+		xdp_prog = rcu_dereference(rq->xdp_prog);
+		if (xdp_prog) {
+			head_skb = receive_mergeable_xdp(dev, vi, rq, xdp_prog, buf, ctx,
+							 len, xdp_xmit, stats);
+			rcu_read_unlock();
+			return head_skb;
+		}
 		rcu_read_unlock();
-		return head_skb;
 	}
-	rcu_read_unlock();
 
-skip_xdp:
 	head_skb = page_to_skb(vi, rq, page, offset, len, truesize, headroom);
 	curr_skb = head_skb;
 
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

The purpose of this patch is to simplify the receive_small().
Separate all the logic of XDP of small into a function.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
 1 file changed, 100 insertions(+), 65 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index de5a579e8603..9b5fd2e0d27f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
 	return NULL;
 }
 
+static struct sk_buff *receive_small_xdp(struct net_device *dev,
+					 struct virtnet_info *vi,
+					 struct receive_queue *rq,
+					 struct bpf_prog *xdp_prog,
+					 void *buf,
+					 unsigned int xdp_headroom,
+					 unsigned int len,
+					 unsigned int *xdp_xmit,
+					 struct virtnet_rq_stats *stats)
+{
+	unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
+	unsigned int headroom = vi->hdr_len + header_offset;
+	struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
+	struct page *page = virt_to_head_page(buf);
+	struct page *xdp_page;
+	unsigned int buflen;
+	struct xdp_buff xdp;
+	struct sk_buff *skb;
+	unsigned int delta = 0;
+	unsigned int metasize = 0;
+	void *orig_data;
+	u32 act;
+
+	if (unlikely(hdr->hdr.gso_type))
+		goto err_xdp;
+
+	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+	if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
+		int offset = buf - page_address(page) + header_offset;
+		unsigned int tlen = len + vi->hdr_len;
+		int num_buf = 1;
+
+		xdp_headroom = virtnet_get_headroom(vi);
+		header_offset = VIRTNET_RX_PAD + xdp_headroom;
+		headroom = vi->hdr_len + header_offset;
+		buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+			SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+		xdp_page = xdp_linearize_page(rq, &num_buf, page,
+					      offset, header_offset,
+					      &tlen);
+		if (!xdp_page)
+			goto err_xdp;
+
+		buf = page_address(xdp_page);
+		put_page(page);
+		page = xdp_page;
+	}
+
+	xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
+	xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
+			 xdp_headroom, len, true);
+	orig_data = xdp.data;
+
+	act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
+
+	switch (act) {
+	case XDP_PASS:
+		/* Recalculate length in case bpf program changed it */
+		delta = orig_data - xdp.data;
+		len = xdp.data_end - xdp.data;
+		metasize = xdp.data - xdp.data_meta;
+		break;
+
+	case XDP_TX:
+	case XDP_REDIRECT:
+		goto xdp_xmit;
+
+	default:
+		goto err_xdp;
+	}
+
+	skb = build_skb(buf, buflen);
+	if (!skb)
+		goto err;
+
+	skb_reserve(skb, headroom - delta);
+	skb_put(skb, len);
+	if (metasize)
+		skb_metadata_set(skb, metasize);
+
+	return skb;
+
+err_xdp:
+	stats->xdp_drops++;
+err:
+	stats->drops++;
+	put_page(page);
+xdp_xmit:
+	return NULL;
+}
+
 static struct sk_buff *receive_small(struct net_device *dev,
 				     struct virtnet_info *vi,
 				     struct receive_queue *rq,
@@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
 			      SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 	struct page *page = virt_to_head_page(buf);
-	unsigned int delta = 0;
-	struct page *xdp_page;
-	unsigned int metasize = 0;
 
 	len -= vi->hdr_len;
 	stats->bytes += len;
@@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	rcu_read_lock();
 	xdp_prog = rcu_dereference(rq->xdp_prog);
 	if (xdp_prog) {
-		struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
-		struct xdp_buff xdp;
-		void *orig_data;
-		u32 act;
-
-		if (unlikely(hdr->hdr.gso_type))
-			goto err_xdp;
-
-		if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
-			int offset = buf - page_address(page) + header_offset;
-			unsigned int tlen = len + vi->hdr_len;
-			int num_buf = 1;
-
-			xdp_headroom = virtnet_get_headroom(vi);
-			header_offset = VIRTNET_RX_PAD + xdp_headroom;
-			headroom = vi->hdr_len + header_offset;
-			buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
-				 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-			xdp_page = xdp_linearize_page(rq, &num_buf, page,
-						      offset, header_offset,
-						      &tlen);
-			if (!xdp_page)
-				goto err_xdp;
-
-			buf = page_address(xdp_page);
-			put_page(page);
-			page = xdp_page;
-		}
-
-		xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
-		xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
-				 xdp_headroom, len, true);
-		orig_data = xdp.data;
-
-		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
-
-		switch (act) {
-		case XDP_PASS:
-			/* Recalculate length in case bpf program changed it */
-			delta = orig_data - xdp.data;
-			len = xdp.data_end - xdp.data;
-			metasize = xdp.data - xdp.data_meta;
-			break;
-		case XDP_TX:
-		case XDP_REDIRECT:
-			rcu_read_unlock();
-			goto xdp_xmit;
-		default:
-			goto err_xdp;
-		}
+		skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
+					len, xdp_xmit, stats);
+		rcu_read_unlock();
+		return skb;
 	}
 	rcu_read_unlock();
 
@@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	skb = build_skb(buf, buflen);
 	if (!skb)
 		goto err;
-	skb_reserve(skb, headroom - delta);
+	skb_reserve(skb, headroom);
 	skb_put(skb, len);
-	if (!xdp_prog) {
-		buf += header_offset;
-		memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
-	} /* keep zeroed vnet hdr since XDP is loaded */
-
-	if (metasize)
-		skb_metadata_set(skb, metasize);
 
+	buf += header_offset;
+	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
 	return skb;
 
-err_xdp:
-	rcu_read_unlock();
-	stats->xdp_drops++;
 err:
 	stats->drops++;
 	put_page(page);
-xdp_xmit:
 	return NULL;
 }
 
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

The purpose of this patch is to simplify the receive_small().
Separate all the logic of XDP of small into a function.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
 1 file changed, 100 insertions(+), 65 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index de5a579e8603..9b5fd2e0d27f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
 	return NULL;
 }
 
+static struct sk_buff *receive_small_xdp(struct net_device *dev,
+					 struct virtnet_info *vi,
+					 struct receive_queue *rq,
+					 struct bpf_prog *xdp_prog,
+					 void *buf,
+					 unsigned int xdp_headroom,
+					 unsigned int len,
+					 unsigned int *xdp_xmit,
+					 struct virtnet_rq_stats *stats)
+{
+	unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
+	unsigned int headroom = vi->hdr_len + header_offset;
+	struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
+	struct page *page = virt_to_head_page(buf);
+	struct page *xdp_page;
+	unsigned int buflen;
+	struct xdp_buff xdp;
+	struct sk_buff *skb;
+	unsigned int delta = 0;
+	unsigned int metasize = 0;
+	void *orig_data;
+	u32 act;
+
+	if (unlikely(hdr->hdr.gso_type))
+		goto err_xdp;
+
+	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+	if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
+		int offset = buf - page_address(page) + header_offset;
+		unsigned int tlen = len + vi->hdr_len;
+		int num_buf = 1;
+
+		xdp_headroom = virtnet_get_headroom(vi);
+		header_offset = VIRTNET_RX_PAD + xdp_headroom;
+		headroom = vi->hdr_len + header_offset;
+		buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+			SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+		xdp_page = xdp_linearize_page(rq, &num_buf, page,
+					      offset, header_offset,
+					      &tlen);
+		if (!xdp_page)
+			goto err_xdp;
+
+		buf = page_address(xdp_page);
+		put_page(page);
+		page = xdp_page;
+	}
+
+	xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
+	xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
+			 xdp_headroom, len, true);
+	orig_data = xdp.data;
+
+	act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
+
+	switch (act) {
+	case XDP_PASS:
+		/* Recalculate length in case bpf program changed it */
+		delta = orig_data - xdp.data;
+		len = xdp.data_end - xdp.data;
+		metasize = xdp.data - xdp.data_meta;
+		break;
+
+	case XDP_TX:
+	case XDP_REDIRECT:
+		goto xdp_xmit;
+
+	default:
+		goto err_xdp;
+	}
+
+	skb = build_skb(buf, buflen);
+	if (!skb)
+		goto err;
+
+	skb_reserve(skb, headroom - delta);
+	skb_put(skb, len);
+	if (metasize)
+		skb_metadata_set(skb, metasize);
+
+	return skb;
+
+err_xdp:
+	stats->xdp_drops++;
+err:
+	stats->drops++;
+	put_page(page);
+xdp_xmit:
+	return NULL;
+}
+
 static struct sk_buff *receive_small(struct net_device *dev,
 				     struct virtnet_info *vi,
 				     struct receive_queue *rq,
@@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
 			      SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 	struct page *page = virt_to_head_page(buf);
-	unsigned int delta = 0;
-	struct page *xdp_page;
-	unsigned int metasize = 0;
 
 	len -= vi->hdr_len;
 	stats->bytes += len;
@@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	rcu_read_lock();
 	xdp_prog = rcu_dereference(rq->xdp_prog);
 	if (xdp_prog) {
-		struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
-		struct xdp_buff xdp;
-		void *orig_data;
-		u32 act;
-
-		if (unlikely(hdr->hdr.gso_type))
-			goto err_xdp;
-
-		if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
-			int offset = buf - page_address(page) + header_offset;
-			unsigned int tlen = len + vi->hdr_len;
-			int num_buf = 1;
-
-			xdp_headroom = virtnet_get_headroom(vi);
-			header_offset = VIRTNET_RX_PAD + xdp_headroom;
-			headroom = vi->hdr_len + header_offset;
-			buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
-				 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-			xdp_page = xdp_linearize_page(rq, &num_buf, page,
-						      offset, header_offset,
-						      &tlen);
-			if (!xdp_page)
-				goto err_xdp;
-
-			buf = page_address(xdp_page);
-			put_page(page);
-			page = xdp_page;
-		}
-
-		xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
-		xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
-				 xdp_headroom, len, true);
-		orig_data = xdp.data;
-
-		act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
-
-		switch (act) {
-		case XDP_PASS:
-			/* Recalculate length in case bpf program changed it */
-			delta = orig_data - xdp.data;
-			len = xdp.data_end - xdp.data;
-			metasize = xdp.data - xdp.data_meta;
-			break;
-		case XDP_TX:
-		case XDP_REDIRECT:
-			rcu_read_unlock();
-			goto xdp_xmit;
-		default:
-			goto err_xdp;
-		}
+		skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
+					len, xdp_xmit, stats);
+		rcu_read_unlock();
+		return skb;
 	}
 	rcu_read_unlock();
 
@@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	skb = build_skb(buf, buflen);
 	if (!skb)
 		goto err;
-	skb_reserve(skb, headroom - delta);
+	skb_reserve(skb, headroom);
 	skb_put(skb, len);
-	if (!xdp_prog) {
-		buf += header_offset;
-		memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
-	} /* keep zeroed vnet hdr since XDP is loaded */
-
-	if (metasize)
-		skb_metadata_set(skb, metasize);
 
+	buf += header_offset;
+	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
 	return skb;
 
-err_xdp:
-	rcu_read_unlock();
-	stats->xdp_drops++;
 err:
 	stats->drops++;
 	put_page(page);
-xdp_xmit:
 	return NULL;
 }
 
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 11/15] virtio_net: small: optimize code
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

In the case of XDP-PASS, skb_reserve uses the delta to compatible
non-XDP, now remove this logic.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 9b5fd2e0d27f..5bc3dca0f60c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -949,9 +949,7 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
 	unsigned int buflen;
 	struct xdp_buff xdp;
 	struct sk_buff *skb;
-	unsigned int delta = 0;
 	unsigned int metasize = 0;
-	void *orig_data;
 	u32 act;
 
 	if (unlikely(hdr->hdr.gso_type))
@@ -984,14 +982,12 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
 	xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
 	xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
 			 xdp_headroom, len, true);
-	orig_data = xdp.data;
 
 	act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
 
 	switch (act) {
 	case XDP_PASS:
 		/* Recalculate length in case bpf program changed it */
-		delta = orig_data - xdp.data;
 		len = xdp.data_end - xdp.data;
 		metasize = xdp.data - xdp.data_meta;
 		break;
@@ -1008,7 +1004,7 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
 	if (!skb)
 		goto err;
 
-	skb_reserve(skb, headroom - delta);
+	skb_reserve(skb, xdp.data - buf);
 	skb_put(skb, len);
 	if (metasize)
 		skb_metadata_set(skb, metasize);
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 11/15] virtio_net: small: optimize code
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

In the case of XDP-PASS, skb_reserve uses the delta to compatible
non-XDP, now remove this logic.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/virtio_net.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 9b5fd2e0d27f..5bc3dca0f60c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -949,9 +949,7 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
 	unsigned int buflen;
 	struct xdp_buff xdp;
 	struct sk_buff *skb;
-	unsigned int delta = 0;
 	unsigned int metasize = 0;
-	void *orig_data;
 	u32 act;
 
 	if (unlikely(hdr->hdr.gso_type))
@@ -984,14 +982,12 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
 	xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
 	xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
 			 xdp_headroom, len, true);
-	orig_data = xdp.data;
 
 	act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
 
 	switch (act) {
 	case XDP_PASS:
 		/* Recalculate length in case bpf program changed it */
-		delta = orig_data - xdp.data;
 		len = xdp.data_end - xdp.data;
 		metasize = xdp.data - xdp.data_meta;
 		break;
@@ -1008,7 +1004,7 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
 	if (!skb)
 		goto err;
 
-	skb_reserve(skb, headroom - delta);
+	skb_reserve(skb, xdp.data - buf);
 	skb_put(skb, len);
 	if (metasize)
 		skb_metadata_set(skb, metasize);
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 12/15] virtio_net: small: optimize code
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

Avoid the problem that some variables(headroom and so on) will repeat
the calculation when process xdp.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 5bc3dca0f60c..601c0e7fc32b 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1031,11 +1031,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	struct sk_buff *skb;
 	struct bpf_prog *xdp_prog;
 	unsigned int xdp_headroom = (unsigned long)ctx;
-	unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
-	unsigned int headroom = vi->hdr_len + header_offset;
-	unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
-			      SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 	struct page *page = virt_to_head_page(buf);
+	unsigned int header_offset;
+	unsigned int headroom;
+	unsigned int buflen;
 
 	len -= vi->hdr_len;
 	stats->bytes += len;
@@ -1063,6 +1062,11 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	rcu_read_unlock();
 
 skip_xdp:
+	header_offset = VIRTNET_RX_PAD + xdp_headroom;
+	headroom = vi->hdr_len + header_offset;
+	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
 	skb = build_skb(buf, buflen);
 	if (!skb)
 		goto err;
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 12/15] virtio_net: small: optimize code
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

Avoid the problem that some variables(headroom and so on) will repeat
the calculation when process xdp.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 5bc3dca0f60c..601c0e7fc32b 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1031,11 +1031,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	struct sk_buff *skb;
 	struct bpf_prog *xdp_prog;
 	unsigned int xdp_headroom = (unsigned long)ctx;
-	unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
-	unsigned int headroom = vi->hdr_len + header_offset;
-	unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
-			      SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 	struct page *page = virt_to_head_page(buf);
+	unsigned int header_offset;
+	unsigned int headroom;
+	unsigned int buflen;
 
 	len -= vi->hdr_len;
 	stats->bytes += len;
@@ -1063,6 +1062,11 @@ static struct sk_buff *receive_small(struct net_device *dev,
 	rcu_read_unlock();
 
 skip_xdp:
+	header_offset = VIRTNET_RX_PAD + xdp_headroom;
+	headroom = vi->hdr_len + header_offset;
+	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
 	skb = build_skb(buf, buflen);
 	if (!skb)
 		goto err;
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 13/15] virtio_net: small: remove skip_xdp
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

now, the process of xdp is simple, we can remove the skip_xdp.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 601c0e7fc32b..d2973c8fa48c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1028,13 +1028,12 @@ static struct sk_buff *receive_small(struct net_device *dev,
 				     unsigned int *xdp_xmit,
 				     struct virtnet_rq_stats *stats)
 {
-	struct sk_buff *skb;
-	struct bpf_prog *xdp_prog;
 	unsigned int xdp_headroom = (unsigned long)ctx;
 	struct page *page = virt_to_head_page(buf);
 	unsigned int header_offset;
 	unsigned int headroom;
 	unsigned int buflen;
+	struct sk_buff *skb;
 
 	len -= vi->hdr_len;
 	stats->bytes += len;
@@ -1046,22 +1045,21 @@ static struct sk_buff *receive_small(struct net_device *dev,
 		goto err;
 	}
 
-	if (likely(!vi->xdp_enabled)) {
-		xdp_prog = NULL;
-		goto skip_xdp;
-	}
+	if (unlikely(vi->xdp_enabled)) {
+		struct bpf_prog *xdp_prog;
 
-	rcu_read_lock();
-	xdp_prog = rcu_dereference(rq->xdp_prog);
-	if (xdp_prog) {
-		skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
-					len, xdp_xmit, stats);
+		rcu_read_lock();
+		xdp_prog = rcu_dereference(rq->xdp_prog);
+		if (xdp_prog) {
+			skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf,
+						xdp_headroom, len, xdp_xmit,
+						stats);
+			rcu_read_unlock();
+			return skb;
+		}
 		rcu_read_unlock();
-		return skb;
 	}
-	rcu_read_unlock();
 
-skip_xdp:
 	header_offset = VIRTNET_RX_PAD + xdp_headroom;
 	headroom = vi->hdr_len + header_offset;
 	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 13/15] virtio_net: small: remove skip_xdp
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

now, the process of xdp is simple, we can remove the skip_xdp.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 601c0e7fc32b..d2973c8fa48c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1028,13 +1028,12 @@ static struct sk_buff *receive_small(struct net_device *dev,
 				     unsigned int *xdp_xmit,
 				     struct virtnet_rq_stats *stats)
 {
-	struct sk_buff *skb;
-	struct bpf_prog *xdp_prog;
 	unsigned int xdp_headroom = (unsigned long)ctx;
 	struct page *page = virt_to_head_page(buf);
 	unsigned int header_offset;
 	unsigned int headroom;
 	unsigned int buflen;
+	struct sk_buff *skb;
 
 	len -= vi->hdr_len;
 	stats->bytes += len;
@@ -1046,22 +1045,21 @@ static struct sk_buff *receive_small(struct net_device *dev,
 		goto err;
 	}
 
-	if (likely(!vi->xdp_enabled)) {
-		xdp_prog = NULL;
-		goto skip_xdp;
-	}
+	if (unlikely(vi->xdp_enabled)) {
+		struct bpf_prog *xdp_prog;
 
-	rcu_read_lock();
-	xdp_prog = rcu_dereference(rq->xdp_prog);
-	if (xdp_prog) {
-		skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
-					len, xdp_xmit, stats);
+		rcu_read_lock();
+		xdp_prog = rcu_dereference(rq->xdp_prog);
+		if (xdp_prog) {
+			skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf,
+						xdp_headroom, len, xdp_xmit,
+						stats);
+			rcu_read_unlock();
+			return skb;
+		}
 		rcu_read_unlock();
-		return skb;
 	}
-	rcu_read_unlock();
 
-skip_xdp:
 	header_offset = VIRTNET_RX_PAD + xdp_headroom;
 	headroom = vi->hdr_len + header_offset;
 	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 14/15] virtio_net: introduce receive_small_build_xdp
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

Simplifying receive_small() function. Bringing the logic relating to
build_skb together.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 48 ++++++++++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d2973c8fa48c..811cf1046df2 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -931,6 +931,34 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
 	return NULL;
 }
 
+static struct sk_buff *receive_small_build_skb(struct virtnet_info *vi,
+					       unsigned int xdp_headroom,
+					       void *buf,
+					       unsigned int len)
+{
+	unsigned int header_offset;
+	unsigned int headroom;
+	unsigned int buflen;
+	struct sk_buff *skb;
+
+	header_offset = VIRTNET_RX_PAD + xdp_headroom;
+	headroom = vi->hdr_len + header_offset;
+	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+	skb = build_skb(buf, buflen);
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, headroom);
+	skb_put(skb, len);
+
+	buf += header_offset;
+	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
+
+	return skb;
+}
+
 static struct sk_buff *receive_small_xdp(struct net_device *dev,
 					 struct virtnet_info *vi,
 					 struct receive_queue *rq,
@@ -1030,9 +1058,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
 {
 	unsigned int xdp_headroom = (unsigned long)ctx;
 	struct page *page = virt_to_head_page(buf);
-	unsigned int header_offset;
-	unsigned int headroom;
-	unsigned int buflen;
 	struct sk_buff *skb;
 
 	len -= vi->hdr_len;
@@ -1060,20 +1085,9 @@ static struct sk_buff *receive_small(struct net_device *dev,
 		rcu_read_unlock();
 	}
 
-	header_offset = VIRTNET_RX_PAD + xdp_headroom;
-	headroom = vi->hdr_len + header_offset;
-	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
-		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-
-	skb = build_skb(buf, buflen);
-	if (!skb)
-		goto err;
-	skb_reserve(skb, headroom);
-	skb_put(skb, len);
-
-	buf += header_offset;
-	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
-	return skb;
+	skb = receive_small_build_skb(vi, xdp_headroom, buf, len);
+	if (likely(skb))
+		return skb;
 
 err:
 	stats->drops++;
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 14/15] virtio_net: introduce receive_small_build_xdp
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

Simplifying receive_small() function. Bringing the logic relating to
build_skb together.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 48 ++++++++++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d2973c8fa48c..811cf1046df2 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -931,6 +931,34 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
 	return NULL;
 }
 
+static struct sk_buff *receive_small_build_skb(struct virtnet_info *vi,
+					       unsigned int xdp_headroom,
+					       void *buf,
+					       unsigned int len)
+{
+	unsigned int header_offset;
+	unsigned int headroom;
+	unsigned int buflen;
+	struct sk_buff *skb;
+
+	header_offset = VIRTNET_RX_PAD + xdp_headroom;
+	headroom = vi->hdr_len + header_offset;
+	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+	skb = build_skb(buf, buflen);
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, headroom);
+	skb_put(skb, len);
+
+	buf += header_offset;
+	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
+
+	return skb;
+}
+
 static struct sk_buff *receive_small_xdp(struct net_device *dev,
 					 struct virtnet_info *vi,
 					 struct receive_queue *rq,
@@ -1030,9 +1058,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
 {
 	unsigned int xdp_headroom = (unsigned long)ctx;
 	struct page *page = virt_to_head_page(buf);
-	unsigned int header_offset;
-	unsigned int headroom;
-	unsigned int buflen;
 	struct sk_buff *skb;
 
 	len -= vi->hdr_len;
@@ -1060,20 +1085,9 @@ static struct sk_buff *receive_small(struct net_device *dev,
 		rcu_read_unlock();
 	}
 
-	header_offset = VIRTNET_RX_PAD + xdp_headroom;
-	headroom = vi->hdr_len + header_offset;
-	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
-		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-
-	skb = build_skb(buf, buflen);
-	if (!skb)
-		goto err;
-	skb_reserve(skb, headroom);
-	skb_put(skb, len);
-
-	buf += header_offset;
-	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
-	return skb;
+	skb = receive_small_build_skb(vi, xdp_headroom, buf, len);
+	if (likely(skb))
+		return skb;
 
 err:
 	stats->drops++;
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 15/15] virtio_net: introduce virtnet_build_skb()
  2023-04-23 10:57 ` Xuan Zhuo
@ 2023-04-23 10:57   ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Michael S. Tsirkin, Jason Wang, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

This logic is used in multiple places, now we separate it into
a helper.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 811cf1046df2..f768e683dadb 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -443,6 +443,22 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx)
 	return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1);
 }
 
+static struct sk_buff *virtnet_build_skb(void *buf, unsigned int buflen,
+					 unsigned int headroom,
+					 unsigned int len)
+{
+	struct sk_buff *skb;
+
+	skb = build_skb(buf, buflen);
+	if (unlikely(!skb))
+		return NULL;
+
+	skb_reserve(skb, headroom);
+	skb_put(skb, len);
+
+	return skb;
+}
+
 /* Called from bottom half context */
 static struct sk_buff *page_to_skb(struct virtnet_info *vi,
 				   struct receive_queue *rq,
@@ -476,13 +492,10 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
 
 	/* copy small packet so we can reuse these pages */
 	if (!NET_IP_ALIGN && len > GOOD_COPY_LEN && tailroom >= shinfo_size) {
-		skb = build_skb(buf, truesize);
+		skb = virtnet_build_skb(buf, truesize, p - buf, len);
 		if (unlikely(!skb))
 			return NULL;
 
-		skb_reserve(skb, p - buf);
-		skb_put(skb, len);
-
 		page = (struct page *)page->private;
 		if (page)
 			give_pages(rq, page);
@@ -946,13 +959,10 @@ static struct sk_buff *receive_small_build_skb(struct virtnet_info *vi,
 	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
 		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
-	skb = build_skb(buf, buflen);
-	if (!skb)
+	skb = virtnet_build_skb(buf, buflen, headroom, len);
+	if (unlikely(!skb))
 		return NULL;
 
-	skb_reserve(skb, headroom);
-	skb_put(skb, len);
-
 	buf += header_offset;
 	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
 
@@ -1028,12 +1038,10 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
 		goto err_xdp;
 	}
 
-	skb = build_skb(buf, buflen);
-	if (!skb)
+	skb = virtnet_build_skb(buf, buflen, xdp.data - buf, len);
+	if (unlikely(!skb))
 		goto err;
 
-	skb_reserve(skb, xdp.data - buf);
-	skb_put(skb, len);
 	if (metasize)
 		skb_metadata_set(skb, metasize);
 
-- 
2.32.0.3.g01195cf9f


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH net-next v3 15/15] virtio_net: introduce virtnet_build_skb()
@ 2023-04-23 10:57   ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-23 10:57 UTC (permalink / raw)
  To: netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

This logic is used in multiple places, now we separate it into
a helper.

Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 811cf1046df2..f768e683dadb 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -443,6 +443,22 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx)
 	return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1);
 }
 
+static struct sk_buff *virtnet_build_skb(void *buf, unsigned int buflen,
+					 unsigned int headroom,
+					 unsigned int len)
+{
+	struct sk_buff *skb;
+
+	skb = build_skb(buf, buflen);
+	if (unlikely(!skb))
+		return NULL;
+
+	skb_reserve(skb, headroom);
+	skb_put(skb, len);
+
+	return skb;
+}
+
 /* Called from bottom half context */
 static struct sk_buff *page_to_skb(struct virtnet_info *vi,
 				   struct receive_queue *rq,
@@ -476,13 +492,10 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
 
 	/* copy small packet so we can reuse these pages */
 	if (!NET_IP_ALIGN && len > GOOD_COPY_LEN && tailroom >= shinfo_size) {
-		skb = build_skb(buf, truesize);
+		skb = virtnet_build_skb(buf, truesize, p - buf, len);
 		if (unlikely(!skb))
 			return NULL;
 
-		skb_reserve(skb, p - buf);
-		skb_put(skb, len);
-
 		page = (struct page *)page->private;
 		if (page)
 			give_pages(rq, page);
@@ -946,13 +959,10 @@ static struct sk_buff *receive_small_build_skb(struct virtnet_info *vi,
 	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
 		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
-	skb = build_skb(buf, buflen);
-	if (!skb)
+	skb = virtnet_build_skb(buf, buflen, headroom, len);
+	if (unlikely(!skb))
 		return NULL;
 
-	skb_reserve(skb, headroom);
-	skb_put(skb, len);
-
 	buf += header_offset;
 	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
 
@@ -1028,12 +1038,10 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
 		goto err_xdp;
 	}
 
-	skb = build_skb(buf, buflen);
-	if (!skb)
+	skb = virtnet_build_skb(buf, buflen, xdp.data - buf, len);
+	if (unlikely(!skb))
 		goto err;
 
-	skb_reserve(skb, xdp.data - buf);
-	skb_put(skb, len);
 	if (metasize)
 		skb_metadata_set(skb, metasize);
 
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 07/15] virtio_net: auto release xdp shinfo
  2023-04-23 10:57   ` Xuan Zhuo
@ 2023-04-25  7:41     ` Jason Wang
  -1 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-25  7:41 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: netdev, Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

On Sun, Apr 23, 2023 at 6:57 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> virtnet_build_xdp_buff_mrg() and virtnet_xdp_handler() auto
> release xdp shinfo then the caller no need to careful the xdp shinfo.

Thinking of this, I think releasing frags in
virtnet_build_xdp_buff_mrg() is fine. But for virtnet_xdp_handler(),
it's better to be done by the caller, since the frags were prepared by
the caller anyhow.

Thanks

>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 29 +++++++++++++++++------------
>  1 file changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 5f37a1cef61e..c6bf425e8844 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -825,7 +825,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
>                 xdpf = xdp_convert_buff_to_frame(xdp);
>                 if (unlikely(!xdpf)) {
>                         netdev_dbg(dev, "convert buff to frame failed for xdp\n");
> -                       return XDP_DROP;
> +                       goto drop;
>                 }
>
>                 err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
> @@ -833,7 +833,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
>                         xdp_return_frame_rx_napi(xdpf);
>                 } else if (unlikely(err < 0)) {
>                         trace_xdp_exception(dev, xdp_prog, act);
> -                       return XDP_DROP;
> +                       goto drop;
>                 }
>                 *xdp_xmit |= VIRTIO_XDP_TX;
>                 return act;
> @@ -842,7 +842,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
>                 stats->xdp_redirects++;
>                 err = xdp_do_redirect(dev, xdp, xdp_prog);
>                 if (err)
> -                       return XDP_DROP;
> +                       goto drop;
>
>                 *xdp_xmit |= VIRTIO_XDP_REDIR;
>                 return act;
> @@ -854,8 +854,12 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
>                 trace_xdp_exception(dev, xdp_prog, act);
>                 fallthrough;
>         case XDP_DROP:
> -               return XDP_DROP;
> +               break;
>         }
> +
> +drop:
> +       put_xdp_frags(xdp);
> +       return XDP_DROP;
>  }
>
>  static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
> @@ -1190,7 +1194,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
>                                  dev->name, *num_buf,
>                                  virtio16_to_cpu(vi->vdev, hdr->num_buffers));
>                         dev->stats.rx_length_errors++;
> -                       return -EINVAL;
> +                       goto err;
>                 }
>
>                 stats->bytes += len;
> @@ -1209,7 +1213,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
>                         pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
>                                  dev->name, len, (unsigned long)(truesize - room));
>                         dev->stats.rx_length_errors++;
> -                       return -EINVAL;
> +                       goto err;
>                 }
>
>                 frag = &shinfo->frags[shinfo->nr_frags++];
> @@ -1224,6 +1228,10 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
>
>         *xdp_frags_truesize = xdp_frags_truesz;
>         return 0;
> +
> +err:
> +       put_xdp_frags(xdp);
> +       return -EINVAL;
>  }
>
>  static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
> @@ -1353,7 +1361,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
>                 err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
>                                                  &num_buf, &xdp_frags_truesz, stats);
>                 if (unlikely(err))
> -                       goto err_xdp_frags;
> +                       goto err_xdp;
>
>                 act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
>
> @@ -1361,7 +1369,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
>                 case XDP_PASS:
>                         head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
>                         if (unlikely(!head_skb))
> -                               goto err_xdp_frags;
> +                               goto err_xdp;
>
>                         rcu_read_unlock();
>                         return head_skb;
> @@ -1370,11 +1378,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
>                         rcu_read_unlock();
>                         goto xdp_xmit;
>                 default:
> -                       break;
> +                       goto err_xdp;
>                 }
> -err_xdp_frags:
> -               put_xdp_frags(&xdp);
> -               goto err_xdp;
>         }
>         rcu_read_unlock();
>
> --
> 2.32.0.3.g01195cf9f
>


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 07/15] virtio_net: auto release xdp shinfo
@ 2023-04-25  7:41     ` Jason Wang
  0 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-25  7:41 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Eric Dumazet, Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

On Sun, Apr 23, 2023 at 6:57 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> virtnet_build_xdp_buff_mrg() and virtnet_xdp_handler() auto
> release xdp shinfo then the caller no need to careful the xdp shinfo.

Thinking of this, I think releasing frags in
virtnet_build_xdp_buff_mrg() is fine. But for virtnet_xdp_handler(),
it's better to be done by the caller, since the frags were prepared by
the caller anyhow.

Thanks

>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 29 +++++++++++++++++------------
>  1 file changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 5f37a1cef61e..c6bf425e8844 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -825,7 +825,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
>                 xdpf = xdp_convert_buff_to_frame(xdp);
>                 if (unlikely(!xdpf)) {
>                         netdev_dbg(dev, "convert buff to frame failed for xdp\n");
> -                       return XDP_DROP;
> +                       goto drop;
>                 }
>
>                 err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
> @@ -833,7 +833,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
>                         xdp_return_frame_rx_napi(xdpf);
>                 } else if (unlikely(err < 0)) {
>                         trace_xdp_exception(dev, xdp_prog, act);
> -                       return XDP_DROP;
> +                       goto drop;
>                 }
>                 *xdp_xmit |= VIRTIO_XDP_TX;
>                 return act;
> @@ -842,7 +842,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
>                 stats->xdp_redirects++;
>                 err = xdp_do_redirect(dev, xdp, xdp_prog);
>                 if (err)
> -                       return XDP_DROP;
> +                       goto drop;
>
>                 *xdp_xmit |= VIRTIO_XDP_REDIR;
>                 return act;
> @@ -854,8 +854,12 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
>                 trace_xdp_exception(dev, xdp_prog, act);
>                 fallthrough;
>         case XDP_DROP:
> -               return XDP_DROP;
> +               break;
>         }
> +
> +drop:
> +       put_xdp_frags(xdp);
> +       return XDP_DROP;
>  }
>
>  static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
> @@ -1190,7 +1194,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
>                                  dev->name, *num_buf,
>                                  virtio16_to_cpu(vi->vdev, hdr->num_buffers));
>                         dev->stats.rx_length_errors++;
> -                       return -EINVAL;
> +                       goto err;
>                 }
>
>                 stats->bytes += len;
> @@ -1209,7 +1213,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
>                         pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
>                                  dev->name, len, (unsigned long)(truesize - room));
>                         dev->stats.rx_length_errors++;
> -                       return -EINVAL;
> +                       goto err;
>                 }
>
>                 frag = &shinfo->frags[shinfo->nr_frags++];
> @@ -1224,6 +1228,10 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
>
>         *xdp_frags_truesize = xdp_frags_truesz;
>         return 0;
> +
> +err:
> +       put_xdp_frags(xdp);
> +       return -EINVAL;
>  }
>
>  static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
> @@ -1353,7 +1361,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
>                 err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
>                                                  &num_buf, &xdp_frags_truesz, stats);
>                 if (unlikely(err))
> -                       goto err_xdp_frags;
> +                       goto err_xdp;
>
>                 act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
>
> @@ -1361,7 +1369,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
>                 case XDP_PASS:
>                         head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
>                         if (unlikely(!head_skb))
> -                               goto err_xdp_frags;
> +                               goto err_xdp;
>
>                         rcu_read_unlock();
>                         return head_skb;
> @@ -1370,11 +1378,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
>                         rcu_read_unlock();
>                         goto xdp_xmit;
>                 default:
> -                       break;
> +                       goto err_xdp;
>                 }
> -err_xdp_frags:
> -               put_xdp_frags(&xdp);
> -               goto err_xdp;
>         }
>         rcu_read_unlock();
>
> --
> 2.32.0.3.g01195cf9f
>

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 07/15] virtio_net: auto release xdp shinfo
  2023-04-25  7:41     ` Jason Wang
@ 2023-04-25  7:46       ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-25  7:46 UTC (permalink / raw)
  To: Jason Wang
  Cc: netdev, Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

On Tue, 25 Apr 2023 15:41:28 +0800, Jason Wang <jasowang@redhat.com> wrote:
> On Sun, Apr 23, 2023 at 6:57 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >
> > virtnet_build_xdp_buff_mrg() and virtnet_xdp_handler() auto
> > release xdp shinfo then the caller no need to careful the xdp shinfo.
>
> Thinking of this, I think releasing frags in
> virtnet_build_xdp_buff_mrg() is fine. But for virtnet_xdp_handler(),
> it's better to be done by the caller, since the frags were prepared by
> the caller anyhow.


I agree this.

Thanks.


>
> Thanks
>
> >
> > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > ---
> >  drivers/net/virtio_net.c | 29 +++++++++++++++++------------
> >  1 file changed, 17 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index 5f37a1cef61e..c6bf425e8844 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -825,7 +825,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> >                 xdpf = xdp_convert_buff_to_frame(xdp);
> >                 if (unlikely(!xdpf)) {
> >                         netdev_dbg(dev, "convert buff to frame failed for xdp\n");
> > -                       return XDP_DROP;
> > +                       goto drop;
> >                 }
> >
> >                 err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
> > @@ -833,7 +833,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> >                         xdp_return_frame_rx_napi(xdpf);
> >                 } else if (unlikely(err < 0)) {
> >                         trace_xdp_exception(dev, xdp_prog, act);
> > -                       return XDP_DROP;
> > +                       goto drop;
> >                 }
> >                 *xdp_xmit |= VIRTIO_XDP_TX;
> >                 return act;
> > @@ -842,7 +842,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> >                 stats->xdp_redirects++;
> >                 err = xdp_do_redirect(dev, xdp, xdp_prog);
> >                 if (err)
> > -                       return XDP_DROP;
> > +                       goto drop;
> >
> >                 *xdp_xmit |= VIRTIO_XDP_REDIR;
> >                 return act;
> > @@ -854,8 +854,12 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> >                 trace_xdp_exception(dev, xdp_prog, act);
> >                 fallthrough;
> >         case XDP_DROP:
> > -               return XDP_DROP;
> > +               break;
> >         }
> > +
> > +drop:
> > +       put_xdp_frags(xdp);
> > +       return XDP_DROP;
> >  }
> >
> >  static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
> > @@ -1190,7 +1194,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
> >                                  dev->name, *num_buf,
> >                                  virtio16_to_cpu(vi->vdev, hdr->num_buffers));
> >                         dev->stats.rx_length_errors++;
> > -                       return -EINVAL;
> > +                       goto err;
> >                 }
> >
> >                 stats->bytes += len;
> > @@ -1209,7 +1213,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
> >                         pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
> >                                  dev->name, len, (unsigned long)(truesize - room));
> >                         dev->stats.rx_length_errors++;
> > -                       return -EINVAL;
> > +                       goto err;
> >                 }
> >
> >                 frag = &shinfo->frags[shinfo->nr_frags++];
> > @@ -1224,6 +1228,10 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
> >
> >         *xdp_frags_truesize = xdp_frags_truesz;
> >         return 0;
> > +
> > +err:
> > +       put_xdp_frags(xdp);
> > +       return -EINVAL;
> >  }
> >
> >  static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
> > @@ -1353,7 +1361,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> >                 err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
> >                                                  &num_buf, &xdp_frags_truesz, stats);
> >                 if (unlikely(err))
> > -                       goto err_xdp_frags;
> > +                       goto err_xdp;
> >
> >                 act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> >
> > @@ -1361,7 +1369,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> >                 case XDP_PASS:
> >                         head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
> >                         if (unlikely(!head_skb))
> > -                               goto err_xdp_frags;
> > +                               goto err_xdp;
> >
> >                         rcu_read_unlock();
> >                         return head_skb;
> > @@ -1370,11 +1378,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> >                         rcu_read_unlock();
> >                         goto xdp_xmit;
> >                 default:
> > -                       break;
> > +                       goto err_xdp;
> >                 }
> > -err_xdp_frags:
> > -               put_xdp_frags(&xdp);
> > -               goto err_xdp;
> >         }
> >         rcu_read_unlock();
> >
> > --
> > 2.32.0.3.g01195cf9f
> >
>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 07/15] virtio_net: auto release xdp shinfo
@ 2023-04-25  7:46       ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-25  7:46 UTC (permalink / raw)
  To: Jason Wang
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Eric Dumazet, Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

On Tue, 25 Apr 2023 15:41:28 +0800, Jason Wang <jasowang@redhat.com> wrote:
> On Sun, Apr 23, 2023 at 6:57 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >
> > virtnet_build_xdp_buff_mrg() and virtnet_xdp_handler() auto
> > release xdp shinfo then the caller no need to careful the xdp shinfo.
>
> Thinking of this, I think releasing frags in
> virtnet_build_xdp_buff_mrg() is fine. But for virtnet_xdp_handler(),
> it's better to be done by the caller, since the frags were prepared by
> the caller anyhow.


I agree this.

Thanks.


>
> Thanks
>
> >
> > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > ---
> >  drivers/net/virtio_net.c | 29 +++++++++++++++++------------
> >  1 file changed, 17 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index 5f37a1cef61e..c6bf425e8844 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -825,7 +825,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> >                 xdpf = xdp_convert_buff_to_frame(xdp);
> >                 if (unlikely(!xdpf)) {
> >                         netdev_dbg(dev, "convert buff to frame failed for xdp\n");
> > -                       return XDP_DROP;
> > +                       goto drop;
> >                 }
> >
> >                 err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
> > @@ -833,7 +833,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> >                         xdp_return_frame_rx_napi(xdpf);
> >                 } else if (unlikely(err < 0)) {
> >                         trace_xdp_exception(dev, xdp_prog, act);
> > -                       return XDP_DROP;
> > +                       goto drop;
> >                 }
> >                 *xdp_xmit |= VIRTIO_XDP_TX;
> >                 return act;
> > @@ -842,7 +842,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> >                 stats->xdp_redirects++;
> >                 err = xdp_do_redirect(dev, xdp, xdp_prog);
> >                 if (err)
> > -                       return XDP_DROP;
> > +                       goto drop;
> >
> >                 *xdp_xmit |= VIRTIO_XDP_REDIR;
> >                 return act;
> > @@ -854,8 +854,12 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,
> >                 trace_xdp_exception(dev, xdp_prog, act);
> >                 fallthrough;
> >         case XDP_DROP:
> > -               return XDP_DROP;
> > +               break;
> >         }
> > +
> > +drop:
> > +       put_xdp_frags(xdp);
> > +       return XDP_DROP;
> >  }
> >
> >  static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
> > @@ -1190,7 +1194,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
> >                                  dev->name, *num_buf,
> >                                  virtio16_to_cpu(vi->vdev, hdr->num_buffers));
> >                         dev->stats.rx_length_errors++;
> > -                       return -EINVAL;
> > +                       goto err;
> >                 }
> >
> >                 stats->bytes += len;
> > @@ -1209,7 +1213,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
> >                         pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
> >                                  dev->name, len, (unsigned long)(truesize - room));
> >                         dev->stats.rx_length_errors++;
> > -                       return -EINVAL;
> > +                       goto err;
> >                 }
> >
> >                 frag = &shinfo->frags[shinfo->nr_frags++];
> > @@ -1224,6 +1228,10 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
> >
> >         *xdp_frags_truesize = xdp_frags_truesz;
> >         return 0;
> > +
> > +err:
> > +       put_xdp_frags(xdp);
> > +       return -EINVAL;
> >  }
> >
> >  static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
> > @@ -1353,7 +1361,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> >                 err = virtnet_build_xdp_buff_mrg(dev, vi, rq, &xdp, data, len, frame_sz,
> >                                                  &num_buf, &xdp_frags_truesz, stats);
> >                 if (unlikely(err))
> > -                       goto err_xdp_frags;
> > +                       goto err_xdp;
> >
> >                 act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> >
> > @@ -1361,7 +1369,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> >                 case XDP_PASS:
> >                         head_skb = build_skb_from_xdp_buff(dev, vi, &xdp, xdp_frags_truesz);
> >                         if (unlikely(!head_skb))
> > -                               goto err_xdp_frags;
> > +                               goto err_xdp;
> >
> >                         rcu_read_unlock();
> >                         return head_skb;
> > @@ -1370,11 +1378,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> >                         rcu_read_unlock();
> >                         goto xdp_xmit;
> >                 default:
> > -                       break;
> > +                       goto err_xdp;
> >                 }
> > -err_xdp_frags:
> > -               put_xdp_frags(&xdp);
> > -               goto err_xdp;
> >         }
> >         rcu_read_unlock();
> >
> > --
> > 2.32.0.3.g01195cf9f
> >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
  2023-04-23 10:57   ` Xuan Zhuo
@ 2023-04-25  7:58     ` Jason Wang
  -1 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-25  7:58 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Eric Dumazet, Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> The purpose of this patch is to simplify the receive_small().
> Separate all the logic of XDP of small into a function.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
>  1 file changed, 100 insertions(+), 65 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index de5a579e8603..9b5fd2e0d27f 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
>         return NULL;
>  }
>
> +static struct sk_buff *receive_small_xdp(struct net_device *dev,
> +                                        struct virtnet_info *vi,
> +                                        struct receive_queue *rq,
> +                                        struct bpf_prog *xdp_prog,
> +                                        void *buf,
> +                                        unsigned int xdp_headroom,
> +                                        unsigned int len,
> +                                        unsigned int *xdp_xmit,
> +                                        struct virtnet_rq_stats *stats)
> +{
> +       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> +       unsigned int headroom = vi->hdr_len + header_offset;
> +       struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> +       struct page *page = virt_to_head_page(buf);
> +       struct page *xdp_page;
> +       unsigned int buflen;
> +       struct xdp_buff xdp;
> +       struct sk_buff *skb;
> +       unsigned int delta = 0;
> +       unsigned int metasize = 0;
> +       void *orig_data;
> +       u32 act;
> +
> +       if (unlikely(hdr->hdr.gso_type))
> +               goto err_xdp;
> +
> +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> +
> +       if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> +               int offset = buf - page_address(page) + header_offset;
> +               unsigned int tlen = len + vi->hdr_len;
> +               int num_buf = 1;
> +
> +               xdp_headroom = virtnet_get_headroom(vi);
> +               header_offset = VIRTNET_RX_PAD + xdp_headroom;
> +               headroom = vi->hdr_len + header_offset;
> +               buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> +               xdp_page = xdp_linearize_page(rq, &num_buf, page,
> +                                             offset, header_offset,
> +                                             &tlen);
> +               if (!xdp_page)
> +                       goto err_xdp;
> +
> +               buf = page_address(xdp_page);
> +               put_page(page);
> +               page = xdp_page;
> +       }
> +
> +       xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> +       xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> +                        xdp_headroom, len, true);
> +       orig_data = xdp.data;
> +
> +       act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> +
> +       switch (act) {
> +       case XDP_PASS:
> +               /* Recalculate length in case bpf program changed it */
> +               delta = orig_data - xdp.data;
> +               len = xdp.data_end - xdp.data;
> +               metasize = xdp.data - xdp.data_meta;
> +               break;
> +
> +       case XDP_TX:
> +       case XDP_REDIRECT:
> +               goto xdp_xmit;
> +
> +       default:
> +               goto err_xdp;
> +       }
> +
> +       skb = build_skb(buf, buflen);
> +       if (!skb)
> +               goto err;
> +
> +       skb_reserve(skb, headroom - delta);
> +       skb_put(skb, len);
> +       if (metasize)
> +               skb_metadata_set(skb, metasize);
> +
> +       return skb;
> +
> +err_xdp:
> +       stats->xdp_drops++;
> +err:
> +       stats->drops++;
> +       put_page(page);
> +xdp_xmit:
> +       return NULL;
> +}

It looks like some of the comments of the above version is not addressed?

"
So we end up with some code duplication between receive_small() and
receive_small_xdp() on building skbs. Is this intended?
"

Thanks

> +
>  static struct sk_buff *receive_small(struct net_device *dev,
>                                      struct virtnet_info *vi,
>                                      struct receive_queue *rq,
> @@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
>                               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>         struct page *page = virt_to_head_page(buf);
> -       unsigned int delta = 0;
> -       struct page *xdp_page;
> -       unsigned int metasize = 0;
>
>         len -= vi->hdr_len;
>         stats->bytes += len;
> @@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         rcu_read_lock();
>         xdp_prog = rcu_dereference(rq->xdp_prog);
>         if (xdp_prog) {
> -               struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> -               struct xdp_buff xdp;
> -               void *orig_data;
> -               u32 act;
> -
> -               if (unlikely(hdr->hdr.gso_type))
> -                       goto err_xdp;
> -
> -               if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> -                       int offset = buf - page_address(page) + header_offset;
> -                       unsigned int tlen = len + vi->hdr_len;
> -                       int num_buf = 1;
> -
> -                       xdp_headroom = virtnet_get_headroom(vi);
> -                       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> -                       headroom = vi->hdr_len + header_offset;
> -                       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> -                                SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> -                       xdp_page = xdp_linearize_page(rq, &num_buf, page,
> -                                                     offset, header_offset,
> -                                                     &tlen);
> -                       if (!xdp_page)
> -                               goto err_xdp;
> -
> -                       buf = page_address(xdp_page);
> -                       put_page(page);
> -                       page = xdp_page;
> -               }
> -
> -               xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> -               xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> -                                xdp_headroom, len, true);
> -               orig_data = xdp.data;
> -
> -               act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> -
> -               switch (act) {
> -               case XDP_PASS:
> -                       /* Recalculate length in case bpf program changed it */
> -                       delta = orig_data - xdp.data;
> -                       len = xdp.data_end - xdp.data;
> -                       metasize = xdp.data - xdp.data_meta;
> -                       break;
> -               case XDP_TX:
> -               case XDP_REDIRECT:
> -                       rcu_read_unlock();
> -                       goto xdp_xmit;
> -               default:
> -                       goto err_xdp;
> -               }
> +               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> +                                       len, xdp_xmit, stats);
> +               rcu_read_unlock();
> +               return skb;
>         }
>         rcu_read_unlock();
>
> @@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         skb = build_skb(buf, buflen);
>         if (!skb)
>                 goto err;
> -       skb_reserve(skb, headroom - delta);
> +       skb_reserve(skb, headroom);
>         skb_put(skb, len);
> -       if (!xdp_prog) {
> -               buf += header_offset;
> -               memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> -       } /* keep zeroed vnet hdr since XDP is loaded */
> -
> -       if (metasize)
> -               skb_metadata_set(skb, metasize);
>
> +       buf += header_offset;
> +       memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
>         return skb;
>
> -err_xdp:
> -       rcu_read_unlock();
> -       stats->xdp_drops++;
>  err:
>         stats->drops++;
>         put_page(page);
> -xdp_xmit:
>         return NULL;
>  }
>
> --
> 2.32.0.3.g01195cf9f
>

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
@ 2023-04-25  7:58     ` Jason Wang
  0 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-25  7:58 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: netdev, Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> The purpose of this patch is to simplify the receive_small().
> Separate all the logic of XDP of small into a function.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
>  1 file changed, 100 insertions(+), 65 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index de5a579e8603..9b5fd2e0d27f 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
>         return NULL;
>  }
>
> +static struct sk_buff *receive_small_xdp(struct net_device *dev,
> +                                        struct virtnet_info *vi,
> +                                        struct receive_queue *rq,
> +                                        struct bpf_prog *xdp_prog,
> +                                        void *buf,
> +                                        unsigned int xdp_headroom,
> +                                        unsigned int len,
> +                                        unsigned int *xdp_xmit,
> +                                        struct virtnet_rq_stats *stats)
> +{
> +       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> +       unsigned int headroom = vi->hdr_len + header_offset;
> +       struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> +       struct page *page = virt_to_head_page(buf);
> +       struct page *xdp_page;
> +       unsigned int buflen;
> +       struct xdp_buff xdp;
> +       struct sk_buff *skb;
> +       unsigned int delta = 0;
> +       unsigned int metasize = 0;
> +       void *orig_data;
> +       u32 act;
> +
> +       if (unlikely(hdr->hdr.gso_type))
> +               goto err_xdp;
> +
> +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> +
> +       if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> +               int offset = buf - page_address(page) + header_offset;
> +               unsigned int tlen = len + vi->hdr_len;
> +               int num_buf = 1;
> +
> +               xdp_headroom = virtnet_get_headroom(vi);
> +               header_offset = VIRTNET_RX_PAD + xdp_headroom;
> +               headroom = vi->hdr_len + header_offset;
> +               buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> +               xdp_page = xdp_linearize_page(rq, &num_buf, page,
> +                                             offset, header_offset,
> +                                             &tlen);
> +               if (!xdp_page)
> +                       goto err_xdp;
> +
> +               buf = page_address(xdp_page);
> +               put_page(page);
> +               page = xdp_page;
> +       }
> +
> +       xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> +       xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> +                        xdp_headroom, len, true);
> +       orig_data = xdp.data;
> +
> +       act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> +
> +       switch (act) {
> +       case XDP_PASS:
> +               /* Recalculate length in case bpf program changed it */
> +               delta = orig_data - xdp.data;
> +               len = xdp.data_end - xdp.data;
> +               metasize = xdp.data - xdp.data_meta;
> +               break;
> +
> +       case XDP_TX:
> +       case XDP_REDIRECT:
> +               goto xdp_xmit;
> +
> +       default:
> +               goto err_xdp;
> +       }
> +
> +       skb = build_skb(buf, buflen);
> +       if (!skb)
> +               goto err;
> +
> +       skb_reserve(skb, headroom - delta);
> +       skb_put(skb, len);
> +       if (metasize)
> +               skb_metadata_set(skb, metasize);
> +
> +       return skb;
> +
> +err_xdp:
> +       stats->xdp_drops++;
> +err:
> +       stats->drops++;
> +       put_page(page);
> +xdp_xmit:
> +       return NULL;
> +}

It looks like some of the comments of the above version is not addressed?

"
So we end up with some code duplication between receive_small() and
receive_small_xdp() on building skbs. Is this intended?
"

Thanks

> +
>  static struct sk_buff *receive_small(struct net_device *dev,
>                                      struct virtnet_info *vi,
>                                      struct receive_queue *rq,
> @@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
>                               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>         struct page *page = virt_to_head_page(buf);
> -       unsigned int delta = 0;
> -       struct page *xdp_page;
> -       unsigned int metasize = 0;
>
>         len -= vi->hdr_len;
>         stats->bytes += len;
> @@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         rcu_read_lock();
>         xdp_prog = rcu_dereference(rq->xdp_prog);
>         if (xdp_prog) {
> -               struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> -               struct xdp_buff xdp;
> -               void *orig_data;
> -               u32 act;
> -
> -               if (unlikely(hdr->hdr.gso_type))
> -                       goto err_xdp;
> -
> -               if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> -                       int offset = buf - page_address(page) + header_offset;
> -                       unsigned int tlen = len + vi->hdr_len;
> -                       int num_buf = 1;
> -
> -                       xdp_headroom = virtnet_get_headroom(vi);
> -                       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> -                       headroom = vi->hdr_len + header_offset;
> -                       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> -                                SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> -                       xdp_page = xdp_linearize_page(rq, &num_buf, page,
> -                                                     offset, header_offset,
> -                                                     &tlen);
> -                       if (!xdp_page)
> -                               goto err_xdp;
> -
> -                       buf = page_address(xdp_page);
> -                       put_page(page);
> -                       page = xdp_page;
> -               }
> -
> -               xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> -               xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> -                                xdp_headroom, len, true);
> -               orig_data = xdp.data;
> -
> -               act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> -
> -               switch (act) {
> -               case XDP_PASS:
> -                       /* Recalculate length in case bpf program changed it */
> -                       delta = orig_data - xdp.data;
> -                       len = xdp.data_end - xdp.data;
> -                       metasize = xdp.data - xdp.data_meta;
> -                       break;
> -               case XDP_TX:
> -               case XDP_REDIRECT:
> -                       rcu_read_unlock();
> -                       goto xdp_xmit;
> -               default:
> -                       goto err_xdp;
> -               }
> +               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> +                                       len, xdp_xmit, stats);
> +               rcu_read_unlock();
> +               return skb;
>         }
>         rcu_read_unlock();
>
> @@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         skb = build_skb(buf, buflen);
>         if (!skb)
>                 goto err;
> -       skb_reserve(skb, headroom - delta);
> +       skb_reserve(skb, headroom);
>         skb_put(skb, len);
> -       if (!xdp_prog) {
> -               buf += header_offset;
> -               memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> -       } /* keep zeroed vnet hdr since XDP is loaded */
> -
> -       if (metasize)
> -               skb_metadata_set(skb, metasize);
>
> +       buf += header_offset;
> +       memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
>         return skb;
>
> -err_xdp:
> -       rcu_read_unlock();
> -       stats->xdp_drops++;
>  err:
>         stats->drops++;
>         put_page(page);
> -xdp_xmit:
>         return NULL;
>  }
>
> --
> 2.32.0.3.g01195cf9f
>


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
  2023-04-25  7:58     ` Jason Wang
@ 2023-04-25  8:00       ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-25  8:00 UTC (permalink / raw)
  To: Jason Wang
  Cc: netdev, Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

On Tue, 25 Apr 2023 15:58:03 +0800, Jason Wang <jasowang@redhat.com> wrote:
> On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >
> > The purpose of this patch is to simplify the receive_small().
> > Separate all the logic of XDP of small into a function.
> >
> > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > ---
> >  drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
> >  1 file changed, 100 insertions(+), 65 deletions(-)
> >
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index de5a579e8603..9b5fd2e0d27f 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
> >         return NULL;
> >  }
> >
> > +static struct sk_buff *receive_small_xdp(struct net_device *dev,
> > +                                        struct virtnet_info *vi,
> > +                                        struct receive_queue *rq,
> > +                                        struct bpf_prog *xdp_prog,
> > +                                        void *buf,
> > +                                        unsigned int xdp_headroom,
> > +                                        unsigned int len,
> > +                                        unsigned int *xdp_xmit,
> > +                                        struct virtnet_rq_stats *stats)
> > +{
> > +       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > +       unsigned int headroom = vi->hdr_len + header_offset;
> > +       struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > +       struct page *page = virt_to_head_page(buf);
> > +       struct page *xdp_page;
> > +       unsigned int buflen;
> > +       struct xdp_buff xdp;
> > +       struct sk_buff *skb;
> > +       unsigned int delta = 0;
> > +       unsigned int metasize = 0;
> > +       void *orig_data;
> > +       u32 act;
> > +
> > +       if (unlikely(hdr->hdr.gso_type))
> > +               goto err_xdp;
> > +
> > +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > +
> > +       if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > +               int offset = buf - page_address(page) + header_offset;
> > +               unsigned int tlen = len + vi->hdr_len;
> > +               int num_buf = 1;
> > +
> > +               xdp_headroom = virtnet_get_headroom(vi);
> > +               header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > +               headroom = vi->hdr_len + header_offset;
> > +               buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > +               xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > +                                             offset, header_offset,
> > +                                             &tlen);
> > +               if (!xdp_page)
> > +                       goto err_xdp;
> > +
> > +               buf = page_address(xdp_page);
> > +               put_page(page);
> > +               page = xdp_page;
> > +       }
> > +
> > +       xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > +       xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > +                        xdp_headroom, len, true);
> > +       orig_data = xdp.data;
> > +
> > +       act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > +
> > +       switch (act) {
> > +       case XDP_PASS:
> > +               /* Recalculate length in case bpf program changed it */
> > +               delta = orig_data - xdp.data;
> > +               len = xdp.data_end - xdp.data;
> > +               metasize = xdp.data - xdp.data_meta;
> > +               break;
> > +
> > +       case XDP_TX:
> > +       case XDP_REDIRECT:
> > +               goto xdp_xmit;
> > +
> > +       default:
> > +               goto err_xdp;
> > +       }
> > +
> > +       skb = build_skb(buf, buflen);
> > +       if (!skb)
> > +               goto err;
> > +
> > +       skb_reserve(skb, headroom - delta);
> > +       skb_put(skb, len);
> > +       if (metasize)
> > +               skb_metadata_set(skb, metasize);
> > +
> > +       return skb;
> > +
> > +err_xdp:
> > +       stats->xdp_drops++;
> > +err:
> > +       stats->drops++;
> > +       put_page(page);
> > +xdp_xmit:
> > +       return NULL;
> > +}
>
> It looks like some of the comments of the above version is not addressed?
>
> "
> So we end up with some code duplication between receive_small() and
> receive_small_xdp() on building skbs. Is this intended?
> "

I answer you in the #13 commit of the above version. This patch-set has optimize
this with the last two commits. This commit is not unchanged.

Thanks.


>
> Thanks
>
> > +
> >  static struct sk_buff *receive_small(struct net_device *dev,
> >                                      struct virtnet_info *vi,
> >                                      struct receive_queue *rq,
> > @@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> >                               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> >         struct page *page = virt_to_head_page(buf);
> > -       unsigned int delta = 0;
> > -       struct page *xdp_page;
> > -       unsigned int metasize = 0;
> >
> >         len -= vi->hdr_len;
> >         stats->bytes += len;
> > @@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         rcu_read_lock();
> >         xdp_prog = rcu_dereference(rq->xdp_prog);
> >         if (xdp_prog) {
> > -               struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > -               struct xdp_buff xdp;
> > -               void *orig_data;
> > -               u32 act;
> > -
> > -               if (unlikely(hdr->hdr.gso_type))
> > -                       goto err_xdp;
> > -
> > -               if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > -                       int offset = buf - page_address(page) + header_offset;
> > -                       unsigned int tlen = len + vi->hdr_len;
> > -                       int num_buf = 1;
> > -
> > -                       xdp_headroom = virtnet_get_headroom(vi);
> > -                       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > -                       headroom = vi->hdr_len + header_offset;
> > -                       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > -                                SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > -                       xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > -                                                     offset, header_offset,
> > -                                                     &tlen);
> > -                       if (!xdp_page)
> > -                               goto err_xdp;
> > -
> > -                       buf = page_address(xdp_page);
> > -                       put_page(page);
> > -                       page = xdp_page;
> > -               }
> > -
> > -               xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > -               xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > -                                xdp_headroom, len, true);
> > -               orig_data = xdp.data;
> > -
> > -               act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > -
> > -               switch (act) {
> > -               case XDP_PASS:
> > -                       /* Recalculate length in case bpf program changed it */
> > -                       delta = orig_data - xdp.data;
> > -                       len = xdp.data_end - xdp.data;
> > -                       metasize = xdp.data - xdp.data_meta;
> > -                       break;
> > -               case XDP_TX:
> > -               case XDP_REDIRECT:
> > -                       rcu_read_unlock();
> > -                       goto xdp_xmit;
> > -               default:
> > -                       goto err_xdp;
> > -               }
> > +               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> > +                                       len, xdp_xmit, stats);
> > +               rcu_read_unlock();
> > +               return skb;
> >         }
> >         rcu_read_unlock();
> >
> > @@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         skb = build_skb(buf, buflen);
> >         if (!skb)
> >                 goto err;
> > -       skb_reserve(skb, headroom - delta);
> > +       skb_reserve(skb, headroom);
> >         skb_put(skb, len);
> > -       if (!xdp_prog) {
> > -               buf += header_offset;
> > -               memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > -       } /* keep zeroed vnet hdr since XDP is loaded */
> > -
> > -       if (metasize)
> > -               skb_metadata_set(skb, metasize);
> >
> > +       buf += header_offset;
> > +       memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> >         return skb;
> >
> > -err_xdp:
> > -       rcu_read_unlock();
> > -       stats->xdp_drops++;
> >  err:
> >         stats->drops++;
> >         put_page(page);
> > -xdp_xmit:
> >         return NULL;
> >  }
> >
> > --
> > 2.32.0.3.g01195cf9f
> >
>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
@ 2023-04-25  8:00       ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-25  8:00 UTC (permalink / raw)
  To: Jason Wang
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Eric Dumazet, Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

On Tue, 25 Apr 2023 15:58:03 +0800, Jason Wang <jasowang@redhat.com> wrote:
> On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >
> > The purpose of this patch is to simplify the receive_small().
> > Separate all the logic of XDP of small into a function.
> >
> > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > ---
> >  drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
> >  1 file changed, 100 insertions(+), 65 deletions(-)
> >
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index de5a579e8603..9b5fd2e0d27f 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
> >         return NULL;
> >  }
> >
> > +static struct sk_buff *receive_small_xdp(struct net_device *dev,
> > +                                        struct virtnet_info *vi,
> > +                                        struct receive_queue *rq,
> > +                                        struct bpf_prog *xdp_prog,
> > +                                        void *buf,
> > +                                        unsigned int xdp_headroom,
> > +                                        unsigned int len,
> > +                                        unsigned int *xdp_xmit,
> > +                                        struct virtnet_rq_stats *stats)
> > +{
> > +       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > +       unsigned int headroom = vi->hdr_len + header_offset;
> > +       struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > +       struct page *page = virt_to_head_page(buf);
> > +       struct page *xdp_page;
> > +       unsigned int buflen;
> > +       struct xdp_buff xdp;
> > +       struct sk_buff *skb;
> > +       unsigned int delta = 0;
> > +       unsigned int metasize = 0;
> > +       void *orig_data;
> > +       u32 act;
> > +
> > +       if (unlikely(hdr->hdr.gso_type))
> > +               goto err_xdp;
> > +
> > +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > +
> > +       if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > +               int offset = buf - page_address(page) + header_offset;
> > +               unsigned int tlen = len + vi->hdr_len;
> > +               int num_buf = 1;
> > +
> > +               xdp_headroom = virtnet_get_headroom(vi);
> > +               header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > +               headroom = vi->hdr_len + header_offset;
> > +               buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > +               xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > +                                             offset, header_offset,
> > +                                             &tlen);
> > +               if (!xdp_page)
> > +                       goto err_xdp;
> > +
> > +               buf = page_address(xdp_page);
> > +               put_page(page);
> > +               page = xdp_page;
> > +       }
> > +
> > +       xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > +       xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > +                        xdp_headroom, len, true);
> > +       orig_data = xdp.data;
> > +
> > +       act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > +
> > +       switch (act) {
> > +       case XDP_PASS:
> > +               /* Recalculate length in case bpf program changed it */
> > +               delta = orig_data - xdp.data;
> > +               len = xdp.data_end - xdp.data;
> > +               metasize = xdp.data - xdp.data_meta;
> > +               break;
> > +
> > +       case XDP_TX:
> > +       case XDP_REDIRECT:
> > +               goto xdp_xmit;
> > +
> > +       default:
> > +               goto err_xdp;
> > +       }
> > +
> > +       skb = build_skb(buf, buflen);
> > +       if (!skb)
> > +               goto err;
> > +
> > +       skb_reserve(skb, headroom - delta);
> > +       skb_put(skb, len);
> > +       if (metasize)
> > +               skb_metadata_set(skb, metasize);
> > +
> > +       return skb;
> > +
> > +err_xdp:
> > +       stats->xdp_drops++;
> > +err:
> > +       stats->drops++;
> > +       put_page(page);
> > +xdp_xmit:
> > +       return NULL;
> > +}
>
> It looks like some of the comments of the above version is not addressed?
>
> "
> So we end up with some code duplication between receive_small() and
> receive_small_xdp() on building skbs. Is this intended?
> "

I answer you in the #13 commit of the above version. This patch-set has optimize
this with the last two commits. This commit is not unchanged.

Thanks.


>
> Thanks
>
> > +
> >  static struct sk_buff *receive_small(struct net_device *dev,
> >                                      struct virtnet_info *vi,
> >                                      struct receive_queue *rq,
> > @@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> >                               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> >         struct page *page = virt_to_head_page(buf);
> > -       unsigned int delta = 0;
> > -       struct page *xdp_page;
> > -       unsigned int metasize = 0;
> >
> >         len -= vi->hdr_len;
> >         stats->bytes += len;
> > @@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         rcu_read_lock();
> >         xdp_prog = rcu_dereference(rq->xdp_prog);
> >         if (xdp_prog) {
> > -               struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > -               struct xdp_buff xdp;
> > -               void *orig_data;
> > -               u32 act;
> > -
> > -               if (unlikely(hdr->hdr.gso_type))
> > -                       goto err_xdp;
> > -
> > -               if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > -                       int offset = buf - page_address(page) + header_offset;
> > -                       unsigned int tlen = len + vi->hdr_len;
> > -                       int num_buf = 1;
> > -
> > -                       xdp_headroom = virtnet_get_headroom(vi);
> > -                       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > -                       headroom = vi->hdr_len + header_offset;
> > -                       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > -                                SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > -                       xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > -                                                     offset, header_offset,
> > -                                                     &tlen);
> > -                       if (!xdp_page)
> > -                               goto err_xdp;
> > -
> > -                       buf = page_address(xdp_page);
> > -                       put_page(page);
> > -                       page = xdp_page;
> > -               }
> > -
> > -               xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > -               xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > -                                xdp_headroom, len, true);
> > -               orig_data = xdp.data;
> > -
> > -               act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > -
> > -               switch (act) {
> > -               case XDP_PASS:
> > -                       /* Recalculate length in case bpf program changed it */
> > -                       delta = orig_data - xdp.data;
> > -                       len = xdp.data_end - xdp.data;
> > -                       metasize = xdp.data - xdp.data_meta;
> > -                       break;
> > -               case XDP_TX:
> > -               case XDP_REDIRECT:
> > -                       rcu_read_unlock();
> > -                       goto xdp_xmit;
> > -               default:
> > -                       goto err_xdp;
> > -               }
> > +               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> > +                                       len, xdp_xmit, stats);
> > +               rcu_read_unlock();
> > +               return skb;
> >         }
> >         rcu_read_unlock();
> >
> > @@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         skb = build_skb(buf, buflen);
> >         if (!skb)
> >                 goto err;
> > -       skb_reserve(skb, headroom - delta);
> > +       skb_reserve(skb, headroom);
> >         skb_put(skb, len);
> > -       if (!xdp_prog) {
> > -               buf += header_offset;
> > -               memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > -       } /* keep zeroed vnet hdr since XDP is loaded */
> > -
> > -       if (metasize)
> > -               skb_metadata_set(skb, metasize);
> >
> > +       buf += header_offset;
> > +       memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> >         return skb;
> >
> > -err_xdp:
> > -       rcu_read_unlock();
> > -       stats->xdp_drops++;
> >  err:
> >         stats->drops++;
> >         put_page(page);
> > -xdp_xmit:
> >         return NULL;
> >  }
> >
> > --
> > 2.32.0.3.g01195cf9f
> >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
  2023-04-25  8:00       ` Xuan Zhuo
@ 2023-04-25  8:09         ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-25  8:09 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: netdev, Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf,
	Jason Wang

On Tue, 25 Apr 2023 16:00:05 +0800, Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> On Tue, 25 Apr 2023 15:58:03 +0800, Jason Wang <jasowang@redhat.com> wrote:
> > On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> > >
> > > The purpose of this patch is to simplify the receive_small().
> > > Separate all the logic of XDP of small into a function.
> > >
> > > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > ---
> > >  drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
> > >  1 file changed, 100 insertions(+), 65 deletions(-)
> > >
> > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > index de5a579e8603..9b5fd2e0d27f 100644
> > > --- a/drivers/net/virtio_net.c
> > > +++ b/drivers/net/virtio_net.c
> > > @@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
> > >         return NULL;
> > >  }
> > >
> > > +static struct sk_buff *receive_small_xdp(struct net_device *dev,
> > > +                                        struct virtnet_info *vi,
> > > +                                        struct receive_queue *rq,
> > > +                                        struct bpf_prog *xdp_prog,
> > > +                                        void *buf,
> > > +                                        unsigned int xdp_headroom,
> > > +                                        unsigned int len,
> > > +                                        unsigned int *xdp_xmit,
> > > +                                        struct virtnet_rq_stats *stats)
> > > +{
> > > +       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > +       unsigned int headroom = vi->hdr_len + header_offset;
> > > +       struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > > +       struct page *page = virt_to_head_page(buf);
> > > +       struct page *xdp_page;
> > > +       unsigned int buflen;
> > > +       struct xdp_buff xdp;
> > > +       struct sk_buff *skb;
> > > +       unsigned int delta = 0;
> > > +       unsigned int metasize = 0;
> > > +       void *orig_data;
> > > +       u32 act;
> > > +
> > > +       if (unlikely(hdr->hdr.gso_type))
> > > +               goto err_xdp;
> > > +
> > > +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > +
> > > +       if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > > +               int offset = buf - page_address(page) + header_offset;
> > > +               unsigned int tlen = len + vi->hdr_len;
> > > +               int num_buf = 1;
> > > +
> > > +               xdp_headroom = virtnet_get_headroom(vi);
> > > +               header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > +               headroom = vi->hdr_len + header_offset;
> > > +               buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > +               xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > > +                                             offset, header_offset,
> > > +                                             &tlen);
> > > +               if (!xdp_page)
> > > +                       goto err_xdp;
> > > +
> > > +               buf = page_address(xdp_page);
> > > +               put_page(page);
> > > +               page = xdp_page;
> > > +       }
> > > +
> > > +       xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > > +       xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > > +                        xdp_headroom, len, true);
> > > +       orig_data = xdp.data;
> > > +
> > > +       act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > > +
> > > +       switch (act) {
> > > +       case XDP_PASS:
> > > +               /* Recalculate length in case bpf program changed it */
> > > +               delta = orig_data - xdp.data;
> > > +               len = xdp.data_end - xdp.data;
> > > +               metasize = xdp.data - xdp.data_meta;
> > > +               break;
> > > +
> > > +       case XDP_TX:
> > > +       case XDP_REDIRECT:
> > > +               goto xdp_xmit;
> > > +
> > > +       default:
> > > +               goto err_xdp;
> > > +       }
> > > +
> > > +       skb = build_skb(buf, buflen);
> > > +       if (!skb)
> > > +               goto err;
> > > +
> > > +       skb_reserve(skb, headroom - delta);
> > > +       skb_put(skb, len);
> > > +       if (metasize)
> > > +               skb_metadata_set(skb, metasize);
> > > +
> > > +       return skb;
> > > +
> > > +err_xdp:
> > > +       stats->xdp_drops++;
> > > +err:
> > > +       stats->drops++;
> > > +       put_page(page);
> > > +xdp_xmit:
> > > +       return NULL;
> > > +}
> >
> > It looks like some of the comments of the above version is not addressed?
> >
> > "
> > So we end up with some code duplication between receive_small() and
> > receive_small_xdp() on building skbs. Is this intended?
> > "
>
> I answer you in the #13 commit of the above version. This patch-set has optimize
> this with the last two commits. This commit is not unchanged.

Sorry, typo.

"This commit is unchanged."

Thanks.

>
> Thanks.
>
>
> >
> > Thanks
> >
> > > +
> > >  static struct sk_buff *receive_small(struct net_device *dev,
> > >                                      struct virtnet_info *vi,
> > >                                      struct receive_queue *rq,
> > > @@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > >         unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > >                               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > >         struct page *page = virt_to_head_page(buf);
> > > -       unsigned int delta = 0;
> > > -       struct page *xdp_page;
> > > -       unsigned int metasize = 0;
> > >
> > >         len -= vi->hdr_len;
> > >         stats->bytes += len;
> > > @@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > >         rcu_read_lock();
> > >         xdp_prog = rcu_dereference(rq->xdp_prog);
> > >         if (xdp_prog) {
> > > -               struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > > -               struct xdp_buff xdp;
> > > -               void *orig_data;
> > > -               u32 act;
> > > -
> > > -               if (unlikely(hdr->hdr.gso_type))
> > > -                       goto err_xdp;
> > > -
> > > -               if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > > -                       int offset = buf - page_address(page) + header_offset;
> > > -                       unsigned int tlen = len + vi->hdr_len;
> > > -                       int num_buf = 1;
> > > -
> > > -                       xdp_headroom = virtnet_get_headroom(vi);
> > > -                       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > -                       headroom = vi->hdr_len + header_offset;
> > > -                       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > -                                SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > -                       xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > > -                                                     offset, header_offset,
> > > -                                                     &tlen);
> > > -                       if (!xdp_page)
> > > -                               goto err_xdp;
> > > -
> > > -                       buf = page_address(xdp_page);
> > > -                       put_page(page);
> > > -                       page = xdp_page;
> > > -               }
> > > -
> > > -               xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > > -               xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > > -                                xdp_headroom, len, true);
> > > -               orig_data = xdp.data;
> > > -
> > > -               act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > > -
> > > -               switch (act) {
> > > -               case XDP_PASS:
> > > -                       /* Recalculate length in case bpf program changed it */
> > > -                       delta = orig_data - xdp.data;
> > > -                       len = xdp.data_end - xdp.data;
> > > -                       metasize = xdp.data - xdp.data_meta;
> > > -                       break;
> > > -               case XDP_TX:
> > > -               case XDP_REDIRECT:
> > > -                       rcu_read_unlock();
> > > -                       goto xdp_xmit;
> > > -               default:
> > > -                       goto err_xdp;
> > > -               }
> > > +               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> > > +                                       len, xdp_xmit, stats);
> > > +               rcu_read_unlock();
> > > +               return skb;
> > >         }
> > >         rcu_read_unlock();
> > >
> > > @@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > >         skb = build_skb(buf, buflen);
> > >         if (!skb)
> > >                 goto err;
> > > -       skb_reserve(skb, headroom - delta);
> > > +       skb_reserve(skb, headroom);
> > >         skb_put(skb, len);
> > > -       if (!xdp_prog) {
> > > -               buf += header_offset;
> > > -               memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > > -       } /* keep zeroed vnet hdr since XDP is loaded */
> > > -
> > > -       if (metasize)
> > > -               skb_metadata_set(skb, metasize);
> > >
> > > +       buf += header_offset;
> > > +       memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > >         return skb;
> > >
> > > -err_xdp:
> > > -       rcu_read_unlock();
> > > -       stats->xdp_drops++;
> > >  err:
> > >         stats->drops++;
> > >         put_page(page);
> > > -xdp_xmit:
> > >         return NULL;
> > >  }
> > >
> > > --
> > > 2.32.0.3.g01195cf9f
> > >
> >

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
@ 2023-04-25  8:09         ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-25  8:09 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Eric Dumazet, Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

On Tue, 25 Apr 2023 16:00:05 +0800, Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> On Tue, 25 Apr 2023 15:58:03 +0800, Jason Wang <jasowang@redhat.com> wrote:
> > On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> > >
> > > The purpose of this patch is to simplify the receive_small().
> > > Separate all the logic of XDP of small into a function.
> > >
> > > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > ---
> > >  drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
> > >  1 file changed, 100 insertions(+), 65 deletions(-)
> > >
> > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > index de5a579e8603..9b5fd2e0d27f 100644
> > > --- a/drivers/net/virtio_net.c
> > > +++ b/drivers/net/virtio_net.c
> > > @@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
> > >         return NULL;
> > >  }
> > >
> > > +static struct sk_buff *receive_small_xdp(struct net_device *dev,
> > > +                                        struct virtnet_info *vi,
> > > +                                        struct receive_queue *rq,
> > > +                                        struct bpf_prog *xdp_prog,
> > > +                                        void *buf,
> > > +                                        unsigned int xdp_headroom,
> > > +                                        unsigned int len,
> > > +                                        unsigned int *xdp_xmit,
> > > +                                        struct virtnet_rq_stats *stats)
> > > +{
> > > +       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > +       unsigned int headroom = vi->hdr_len + header_offset;
> > > +       struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > > +       struct page *page = virt_to_head_page(buf);
> > > +       struct page *xdp_page;
> > > +       unsigned int buflen;
> > > +       struct xdp_buff xdp;
> > > +       struct sk_buff *skb;
> > > +       unsigned int delta = 0;
> > > +       unsigned int metasize = 0;
> > > +       void *orig_data;
> > > +       u32 act;
> > > +
> > > +       if (unlikely(hdr->hdr.gso_type))
> > > +               goto err_xdp;
> > > +
> > > +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > +
> > > +       if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > > +               int offset = buf - page_address(page) + header_offset;
> > > +               unsigned int tlen = len + vi->hdr_len;
> > > +               int num_buf = 1;
> > > +
> > > +               xdp_headroom = virtnet_get_headroom(vi);
> > > +               header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > +               headroom = vi->hdr_len + header_offset;
> > > +               buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > +               xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > > +                                             offset, header_offset,
> > > +                                             &tlen);
> > > +               if (!xdp_page)
> > > +                       goto err_xdp;
> > > +
> > > +               buf = page_address(xdp_page);
> > > +               put_page(page);
> > > +               page = xdp_page;
> > > +       }
> > > +
> > > +       xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > > +       xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > > +                        xdp_headroom, len, true);
> > > +       orig_data = xdp.data;
> > > +
> > > +       act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > > +
> > > +       switch (act) {
> > > +       case XDP_PASS:
> > > +               /* Recalculate length in case bpf program changed it */
> > > +               delta = orig_data - xdp.data;
> > > +               len = xdp.data_end - xdp.data;
> > > +               metasize = xdp.data - xdp.data_meta;
> > > +               break;
> > > +
> > > +       case XDP_TX:
> > > +       case XDP_REDIRECT:
> > > +               goto xdp_xmit;
> > > +
> > > +       default:
> > > +               goto err_xdp;
> > > +       }
> > > +
> > > +       skb = build_skb(buf, buflen);
> > > +       if (!skb)
> > > +               goto err;
> > > +
> > > +       skb_reserve(skb, headroom - delta);
> > > +       skb_put(skb, len);
> > > +       if (metasize)
> > > +               skb_metadata_set(skb, metasize);
> > > +
> > > +       return skb;
> > > +
> > > +err_xdp:
> > > +       stats->xdp_drops++;
> > > +err:
> > > +       stats->drops++;
> > > +       put_page(page);
> > > +xdp_xmit:
> > > +       return NULL;
> > > +}
> >
> > It looks like some of the comments of the above version is not addressed?
> >
> > "
> > So we end up with some code duplication between receive_small() and
> > receive_small_xdp() on building skbs. Is this intended?
> > "
>
> I answer you in the #13 commit of the above version. This patch-set has optimize
> this with the last two commits. This commit is not unchanged.

Sorry, typo.

"This commit is unchanged."

Thanks.

>
> Thanks.
>
>
> >
> > Thanks
> >
> > > +
> > >  static struct sk_buff *receive_small(struct net_device *dev,
> > >                                      struct virtnet_info *vi,
> > >                                      struct receive_queue *rq,
> > > @@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > >         unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > >                               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > >         struct page *page = virt_to_head_page(buf);
> > > -       unsigned int delta = 0;
> > > -       struct page *xdp_page;
> > > -       unsigned int metasize = 0;
> > >
> > >         len -= vi->hdr_len;
> > >         stats->bytes += len;
> > > @@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > >         rcu_read_lock();
> > >         xdp_prog = rcu_dereference(rq->xdp_prog);
> > >         if (xdp_prog) {
> > > -               struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > > -               struct xdp_buff xdp;
> > > -               void *orig_data;
> > > -               u32 act;
> > > -
> > > -               if (unlikely(hdr->hdr.gso_type))
> > > -                       goto err_xdp;
> > > -
> > > -               if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > > -                       int offset = buf - page_address(page) + header_offset;
> > > -                       unsigned int tlen = len + vi->hdr_len;
> > > -                       int num_buf = 1;
> > > -
> > > -                       xdp_headroom = virtnet_get_headroom(vi);
> > > -                       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > -                       headroom = vi->hdr_len + header_offset;
> > > -                       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > -                                SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > -                       xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > > -                                                     offset, header_offset,
> > > -                                                     &tlen);
> > > -                       if (!xdp_page)
> > > -                               goto err_xdp;
> > > -
> > > -                       buf = page_address(xdp_page);
> > > -                       put_page(page);
> > > -                       page = xdp_page;
> > > -               }
> > > -
> > > -               xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > > -               xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > > -                                xdp_headroom, len, true);
> > > -               orig_data = xdp.data;
> > > -
> > > -               act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > > -
> > > -               switch (act) {
> > > -               case XDP_PASS:
> > > -                       /* Recalculate length in case bpf program changed it */
> > > -                       delta = orig_data - xdp.data;
> > > -                       len = xdp.data_end - xdp.data;
> > > -                       metasize = xdp.data - xdp.data_meta;
> > > -                       break;
> > > -               case XDP_TX:
> > > -               case XDP_REDIRECT:
> > > -                       rcu_read_unlock();
> > > -                       goto xdp_xmit;
> > > -               default:
> > > -                       goto err_xdp;
> > > -               }
> > > +               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> > > +                                       len, xdp_xmit, stats);
> > > +               rcu_read_unlock();
> > > +               return skb;
> > >         }
> > >         rcu_read_unlock();
> > >
> > > @@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > >         skb = build_skb(buf, buflen);
> > >         if (!skb)
> > >                 goto err;
> > > -       skb_reserve(skb, headroom - delta);
> > > +       skb_reserve(skb, headroom);
> > >         skb_put(skb, len);
> > > -       if (!xdp_prog) {
> > > -               buf += header_offset;
> > > -               memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > > -       } /* keep zeroed vnet hdr since XDP is loaded */
> > > -
> > > -       if (metasize)
> > > -               skb_metadata_set(skb, metasize);
> > >
> > > +       buf += header_offset;
> > > +       memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > >         return skb;
> > >
> > > -err_xdp:
> > > -       rcu_read_unlock();
> > > -       stats->xdp_drops++;
> > >  err:
> > >         stats->drops++;
> > >         put_page(page);
> > > -xdp_xmit:
> > >         return NULL;
> > >  }
> > >
> > > --
> > > 2.32.0.3.g01195cf9f
> > >
> >
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 12/15] virtio_net: small: optimize code
  2023-04-23 10:57   ` Xuan Zhuo
@ 2023-04-26  3:08     ` Jason Wang
  -1 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:08 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Eric Dumazet, Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> Avoid the problem that some variables(headroom and so on) will repeat
> the calculation when process xdp.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>

Nit: I think we need to tweak the title, it's better to say what is
optimized. (And it would be better to tweak the title of patch 11 as
well)

Acked-by: Jason Wang <jasowang@redhat.com>

> ---
>  drivers/net/virtio_net.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 5bc3dca0f60c..601c0e7fc32b 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1031,11 +1031,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         struct sk_buff *skb;
>         struct bpf_prog *xdp_prog;
>         unsigned int xdp_headroom = (unsigned long)ctx;
> -       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> -       unsigned int headroom = vi->hdr_len + header_offset;
> -       unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> -                             SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>         struct page *page = virt_to_head_page(buf);
> +       unsigned int header_offset;
> +       unsigned int headroom;
> +       unsigned int buflen;
>
>         len -= vi->hdr_len;
>         stats->bytes += len;
> @@ -1063,6 +1062,11 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         rcu_read_unlock();
>
>  skip_xdp:
> +       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> +       headroom = vi->hdr_len + header_offset;
> +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> +
>         skb = build_skb(buf, buflen);
>         if (!skb)
>                 goto err;
> --
> 2.32.0.3.g01195cf9f
>

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 12/15] virtio_net: small: optimize code
@ 2023-04-26  3:08     ` Jason Wang
  0 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:08 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: netdev, Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> Avoid the problem that some variables(headroom and so on) will repeat
> the calculation when process xdp.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>

Nit: I think we need to tweak the title, it's better to say what is
optimized. (And it would be better to tweak the title of patch 11 as
well)

Acked-by: Jason Wang <jasowang@redhat.com>

> ---
>  drivers/net/virtio_net.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 5bc3dca0f60c..601c0e7fc32b 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1031,11 +1031,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         struct sk_buff *skb;
>         struct bpf_prog *xdp_prog;
>         unsigned int xdp_headroom = (unsigned long)ctx;
> -       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> -       unsigned int headroom = vi->hdr_len + header_offset;
> -       unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> -                             SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>         struct page *page = virt_to_head_page(buf);
> +       unsigned int header_offset;
> +       unsigned int headroom;
> +       unsigned int buflen;
>
>         len -= vi->hdr_len;
>         stats->bytes += len;
> @@ -1063,6 +1062,11 @@ static struct sk_buff *receive_small(struct net_device *dev,
>         rcu_read_unlock();
>
>  skip_xdp:
> +       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> +       headroom = vi->hdr_len + header_offset;
> +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> +
>         skb = build_skb(buf, buflen);
>         if (!skb)
>                 goto err;
> --
> 2.32.0.3.g01195cf9f
>


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 13/15] virtio_net: small: remove skip_xdp
  2023-04-23 10:57   ` Xuan Zhuo
@ 2023-04-26  3:13     ` Jason Wang
  -1 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:13 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: netdev, Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> now, the process of xdp is simple, we can remove the skip_xdp.

I would say the reason why xdp is simple, I think it is because the
skb build path is not shared between XDP and non-XDP case.

Other than this

Acked-by: Jason Wang <jasowang@redhat.com>

Thanks


>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 26 ++++++++++++--------------
>  1 file changed, 12 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 601c0e7fc32b..d2973c8fa48c 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1028,13 +1028,12 @@ static struct sk_buff *receive_small(struct net_device *dev,
>                                      unsigned int *xdp_xmit,
>                                      struct virtnet_rq_stats *stats)
>  {
> -       struct sk_buff *skb;
> -       struct bpf_prog *xdp_prog;
>         unsigned int xdp_headroom = (unsigned long)ctx;
>         struct page *page = virt_to_head_page(buf);
>         unsigned int header_offset;
>         unsigned int headroom;
>         unsigned int buflen;
> +       struct sk_buff *skb;
>
>         len -= vi->hdr_len;
>         stats->bytes += len;
> @@ -1046,22 +1045,21 @@ static struct sk_buff *receive_small(struct net_device *dev,
>                 goto err;
>         }
>
> -       if (likely(!vi->xdp_enabled)) {
> -               xdp_prog = NULL;
> -               goto skip_xdp;
> -       }
> +       if (unlikely(vi->xdp_enabled)) {
> +               struct bpf_prog *xdp_prog;
>
> -       rcu_read_lock();
> -       xdp_prog = rcu_dereference(rq->xdp_prog);
> -       if (xdp_prog) {
> -               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> -                                       len, xdp_xmit, stats);
> +               rcu_read_lock();
> +               xdp_prog = rcu_dereference(rq->xdp_prog);
> +               if (xdp_prog) {
> +                       skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf,
> +                                               xdp_headroom, len, xdp_xmit,
> +                                               stats);
> +                       rcu_read_unlock();
> +                       return skb;
> +               }
>                 rcu_read_unlock();
> -               return skb;
>         }
> -       rcu_read_unlock();
>
> -skip_xdp:
>         header_offset = VIRTNET_RX_PAD + xdp_headroom;
>         headroom = vi->hdr_len + header_offset;
>         buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> --
> 2.32.0.3.g01195cf9f
>


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 13/15] virtio_net: small: remove skip_xdp
@ 2023-04-26  3:13     ` Jason Wang
  0 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:13 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Eric Dumazet, Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> now, the process of xdp is simple, we can remove the skip_xdp.

I would say the reason why xdp is simple, I think it is because the
skb build path is not shared between XDP and non-XDP case.

Other than this

Acked-by: Jason Wang <jasowang@redhat.com>

Thanks


>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>  drivers/net/virtio_net.c | 26 ++++++++++++--------------
>  1 file changed, 12 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 601c0e7fc32b..d2973c8fa48c 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1028,13 +1028,12 @@ static struct sk_buff *receive_small(struct net_device *dev,
>                                      unsigned int *xdp_xmit,
>                                      struct virtnet_rq_stats *stats)
>  {
> -       struct sk_buff *skb;
> -       struct bpf_prog *xdp_prog;
>         unsigned int xdp_headroom = (unsigned long)ctx;
>         struct page *page = virt_to_head_page(buf);
>         unsigned int header_offset;
>         unsigned int headroom;
>         unsigned int buflen;
> +       struct sk_buff *skb;
>
>         len -= vi->hdr_len;
>         stats->bytes += len;
> @@ -1046,22 +1045,21 @@ static struct sk_buff *receive_small(struct net_device *dev,
>                 goto err;
>         }
>
> -       if (likely(!vi->xdp_enabled)) {
> -               xdp_prog = NULL;
> -               goto skip_xdp;
> -       }
> +       if (unlikely(vi->xdp_enabled)) {
> +               struct bpf_prog *xdp_prog;
>
> -       rcu_read_lock();
> -       xdp_prog = rcu_dereference(rq->xdp_prog);
> -       if (xdp_prog) {
> -               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> -                                       len, xdp_xmit, stats);
> +               rcu_read_lock();
> +               xdp_prog = rcu_dereference(rq->xdp_prog);
> +               if (xdp_prog) {
> +                       skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf,
> +                                               xdp_headroom, len, xdp_xmit,
> +                                               stats);
> +                       rcu_read_unlock();
> +                       return skb;
> +               }
>                 rcu_read_unlock();
> -               return skb;
>         }
> -       rcu_read_unlock();
>
> -skip_xdp:
>         header_offset = VIRTNET_RX_PAD + xdp_headroom;
>         headroom = vi->hdr_len + header_offset;
>         buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> --
> 2.32.0.3.g01195cf9f
>

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 14/15] virtio_net: introduce receive_small_build_xdp
  2023-04-23 10:57   ` Xuan Zhuo
@ 2023-04-26  3:15     ` Jason Wang
  -1 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:15 UTC (permalink / raw)
  To: Xuan Zhuo, netdev
  Cc: Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf


在 2023/4/23 18:57, Xuan Zhuo 写道:
> Simplifying receive_small() function. Bringing the logic relating to
> build_skb together.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>


Acked-by: Jason Wang <jasowang@redhat.com>

Thanks


> ---
>   drivers/net/virtio_net.c | 48 ++++++++++++++++++++++++++--------------
>   1 file changed, 31 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index d2973c8fa48c..811cf1046df2 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -931,6 +931,34 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
>   	return NULL;
>   }
>   
> +static struct sk_buff *receive_small_build_skb(struct virtnet_info *vi,
> +					       unsigned int xdp_headroom,
> +					       void *buf,
> +					       unsigned int len)
> +{
> +	unsigned int header_offset;
> +	unsigned int headroom;
> +	unsigned int buflen;
> +	struct sk_buff *skb;
> +
> +	header_offset = VIRTNET_RX_PAD + xdp_headroom;
> +	headroom = vi->hdr_len + header_offset;
> +	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> +		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> +
> +	skb = build_skb(buf, buflen);
> +	if (!skb)
> +		return NULL;
> +
> +	skb_reserve(skb, headroom);
> +	skb_put(skb, len);
> +
> +	buf += header_offset;
> +	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> +
> +	return skb;
> +}
> +
>   static struct sk_buff *receive_small_xdp(struct net_device *dev,
>   					 struct virtnet_info *vi,
>   					 struct receive_queue *rq,
> @@ -1030,9 +1058,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
>   {
>   	unsigned int xdp_headroom = (unsigned long)ctx;
>   	struct page *page = virt_to_head_page(buf);
> -	unsigned int header_offset;
> -	unsigned int headroom;
> -	unsigned int buflen;
>   	struct sk_buff *skb;
>   
>   	len -= vi->hdr_len;
> @@ -1060,20 +1085,9 @@ static struct sk_buff *receive_small(struct net_device *dev,
>   		rcu_read_unlock();
>   	}
>   
> -	header_offset = VIRTNET_RX_PAD + xdp_headroom;
> -	headroom = vi->hdr_len + header_offset;
> -	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> -		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> -
> -	skb = build_skb(buf, buflen);
> -	if (!skb)
> -		goto err;
> -	skb_reserve(skb, headroom);
> -	skb_put(skb, len);
> -
> -	buf += header_offset;
> -	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> -	return skb;
> +	skb = receive_small_build_skb(vi, xdp_headroom, buf, len);
> +	if (likely(skb))
> +		return skb;
>   
>   err:
>   	stats->drops++;


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 14/15] virtio_net: introduce receive_small_build_xdp
@ 2023-04-26  3:15     ` Jason Wang
  0 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:15 UTC (permalink / raw)
  To: Xuan Zhuo, netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller


在 2023/4/23 18:57, Xuan Zhuo 写道:
> Simplifying receive_small() function. Bringing the logic relating to
> build_skb together.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>


Acked-by: Jason Wang <jasowang@redhat.com>

Thanks


> ---
>   drivers/net/virtio_net.c | 48 ++++++++++++++++++++++++++--------------
>   1 file changed, 31 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index d2973c8fa48c..811cf1046df2 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -931,6 +931,34 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
>   	return NULL;
>   }
>   
> +static struct sk_buff *receive_small_build_skb(struct virtnet_info *vi,
> +					       unsigned int xdp_headroom,
> +					       void *buf,
> +					       unsigned int len)
> +{
> +	unsigned int header_offset;
> +	unsigned int headroom;
> +	unsigned int buflen;
> +	struct sk_buff *skb;
> +
> +	header_offset = VIRTNET_RX_PAD + xdp_headroom;
> +	headroom = vi->hdr_len + header_offset;
> +	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> +		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> +
> +	skb = build_skb(buf, buflen);
> +	if (!skb)
> +		return NULL;
> +
> +	skb_reserve(skb, headroom);
> +	skb_put(skb, len);
> +
> +	buf += header_offset;
> +	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> +
> +	return skb;
> +}
> +
>   static struct sk_buff *receive_small_xdp(struct net_device *dev,
>   					 struct virtnet_info *vi,
>   					 struct receive_queue *rq,
> @@ -1030,9 +1058,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
>   {
>   	unsigned int xdp_headroom = (unsigned long)ctx;
>   	struct page *page = virt_to_head_page(buf);
> -	unsigned int header_offset;
> -	unsigned int headroom;
> -	unsigned int buflen;
>   	struct sk_buff *skb;
>   
>   	len -= vi->hdr_len;
> @@ -1060,20 +1085,9 @@ static struct sk_buff *receive_small(struct net_device *dev,
>   		rcu_read_unlock();
>   	}
>   
> -	header_offset = VIRTNET_RX_PAD + xdp_headroom;
> -	headroom = vi->hdr_len + header_offset;
> -	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> -		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> -
> -	skb = build_skb(buf, buflen);
> -	if (!skb)
> -		goto err;
> -	skb_reserve(skb, headroom);
> -	skb_put(skb, len);
> -
> -	buf += header_offset;
> -	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> -	return skb;
> +	skb = receive_small_build_skb(vi, xdp_headroom, buf, len);
> +	if (likely(skb))
> +		return skb;
>   
>   err:
>   	stats->drops++;

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 15/15] virtio_net: introduce virtnet_build_skb()
  2023-04-23 10:57   ` Xuan Zhuo
@ 2023-04-26  3:16     ` Jason Wang
  -1 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:16 UTC (permalink / raw)
  To: Xuan Zhuo, netdev
  Cc: Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf


在 2023/4/23 18:57, Xuan Zhuo 写道:
> This logic is used in multiple places, now we separate it into
> a helper.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>


Acked-by: Jason Wang <jasowang@redhat.com>

Thanks


> ---
>   drivers/net/virtio_net.c | 34 +++++++++++++++++++++-------------
>   1 file changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 811cf1046df2..f768e683dadb 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -443,6 +443,22 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx)
>   	return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1);
>   }
>   
> +static struct sk_buff *virtnet_build_skb(void *buf, unsigned int buflen,
> +					 unsigned int headroom,
> +					 unsigned int len)
> +{
> +	struct sk_buff *skb;
> +
> +	skb = build_skb(buf, buflen);
> +	if (unlikely(!skb))
> +		return NULL;
> +
> +	skb_reserve(skb, headroom);
> +	skb_put(skb, len);
> +
> +	return skb;
> +}
> +
>   /* Called from bottom half context */
>   static struct sk_buff *page_to_skb(struct virtnet_info *vi,
>   				   struct receive_queue *rq,
> @@ -476,13 +492,10 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
>   
>   	/* copy small packet so we can reuse these pages */
>   	if (!NET_IP_ALIGN && len > GOOD_COPY_LEN && tailroom >= shinfo_size) {
> -		skb = build_skb(buf, truesize);
> +		skb = virtnet_build_skb(buf, truesize, p - buf, len);
>   		if (unlikely(!skb))
>   			return NULL;
>   
> -		skb_reserve(skb, p - buf);
> -		skb_put(skb, len);
> -
>   		page = (struct page *)page->private;
>   		if (page)
>   			give_pages(rq, page);
> @@ -946,13 +959,10 @@ static struct sk_buff *receive_small_build_skb(struct virtnet_info *vi,
>   	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
>   		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>   
> -	skb = build_skb(buf, buflen);
> -	if (!skb)
> +	skb = virtnet_build_skb(buf, buflen, headroom, len);
> +	if (unlikely(!skb))
>   		return NULL;
>   
> -	skb_reserve(skb, headroom);
> -	skb_put(skb, len);
> -
>   	buf += header_offset;
>   	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
>   
> @@ -1028,12 +1038,10 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
>   		goto err_xdp;
>   	}
>   
> -	skb = build_skb(buf, buflen);
> -	if (!skb)
> +	skb = virtnet_build_skb(buf, buflen, xdp.data - buf, len);
> +	if (unlikely(!skb))
>   		goto err;
>   
> -	skb_reserve(skb, xdp.data - buf);
> -	skb_put(skb, len);
>   	if (metasize)
>   		skb_metadata_set(skb, metasize);
>   


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 15/15] virtio_net: introduce virtnet_build_skb()
@ 2023-04-26  3:16     ` Jason Wang
  0 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:16 UTC (permalink / raw)
  To: Xuan Zhuo, netdev
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	John Fastabend, Alexei Starovoitov, virtualization, Eric Dumazet,
	Jakub Kicinski, bpf, Paolo Abeni, David S. Miller


在 2023/4/23 18:57, Xuan Zhuo 写道:
> This logic is used in multiple places, now we separate it into
> a helper.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>


Acked-by: Jason Wang <jasowang@redhat.com>

Thanks


> ---
>   drivers/net/virtio_net.c | 34 +++++++++++++++++++++-------------
>   1 file changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 811cf1046df2..f768e683dadb 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -443,6 +443,22 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx)
>   	return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1);
>   }
>   
> +static struct sk_buff *virtnet_build_skb(void *buf, unsigned int buflen,
> +					 unsigned int headroom,
> +					 unsigned int len)
> +{
> +	struct sk_buff *skb;
> +
> +	skb = build_skb(buf, buflen);
> +	if (unlikely(!skb))
> +		return NULL;
> +
> +	skb_reserve(skb, headroom);
> +	skb_put(skb, len);
> +
> +	return skb;
> +}
> +
>   /* Called from bottom half context */
>   static struct sk_buff *page_to_skb(struct virtnet_info *vi,
>   				   struct receive_queue *rq,
> @@ -476,13 +492,10 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
>   
>   	/* copy small packet so we can reuse these pages */
>   	if (!NET_IP_ALIGN && len > GOOD_COPY_LEN && tailroom >= shinfo_size) {
> -		skb = build_skb(buf, truesize);
> +		skb = virtnet_build_skb(buf, truesize, p - buf, len);
>   		if (unlikely(!skb))
>   			return NULL;
>   
> -		skb_reserve(skb, p - buf);
> -		skb_put(skb, len);
> -
>   		page = (struct page *)page->private;
>   		if (page)
>   			give_pages(rq, page);
> @@ -946,13 +959,10 @@ static struct sk_buff *receive_small_build_skb(struct virtnet_info *vi,
>   	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
>   		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
>   
> -	skb = build_skb(buf, buflen);
> -	if (!skb)
> +	skb = virtnet_build_skb(buf, buflen, headroom, len);
> +	if (unlikely(!skb))
>   		return NULL;
>   
> -	skb_reserve(skb, headroom);
> -	skb_put(skb, len);
> -
>   	buf += header_offset;
>   	memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
>   
> @@ -1028,12 +1038,10 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
>   		goto err_xdp;
>   	}
>   
> -	skb = build_skb(buf, buflen);
> -	if (!skb)
> +	skb = virtnet_build_skb(buf, buflen, xdp.data - buf, len);
> +	if (unlikely(!skb))
>   		goto err;
>   
> -	skb_reserve(skb, xdp.data - buf);
> -	skb_put(skb, len);
>   	if (metasize)
>   		skb_metadata_set(skb, metasize);
>   

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
  2023-04-25  8:09         ` Xuan Zhuo
@ 2023-04-26  3:19           ` Jason Wang
  -1 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:19 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Eric Dumazet, Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

On Tue, Apr 25, 2023 at 4:10 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> On Tue, 25 Apr 2023 16:00:05 +0800, Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> > On Tue, 25 Apr 2023 15:58:03 +0800, Jason Wang <jasowang@redhat.com> wrote:
> > > On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> > > >
> > > > The purpose of this patch is to simplify the receive_small().
> > > > Separate all the logic of XDP of small into a function.
> > > >
> > > > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > > ---
> > > >  drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
> > > >  1 file changed, 100 insertions(+), 65 deletions(-)
> > > >
> > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > > index de5a579e8603..9b5fd2e0d27f 100644
> > > > --- a/drivers/net/virtio_net.c
> > > > +++ b/drivers/net/virtio_net.c
> > > > @@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
> > > >         return NULL;
> > > >  }
> > > >
> > > > +static struct sk_buff *receive_small_xdp(struct net_device *dev,
> > > > +                                        struct virtnet_info *vi,
> > > > +                                        struct receive_queue *rq,
> > > > +                                        struct bpf_prog *xdp_prog,
> > > > +                                        void *buf,
> > > > +                                        unsigned int xdp_headroom,
> > > > +                                        unsigned int len,
> > > > +                                        unsigned int *xdp_xmit,
> > > > +                                        struct virtnet_rq_stats *stats)
> > > > +{
> > > > +       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > > +       unsigned int headroom = vi->hdr_len + header_offset;
> > > > +       struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > > > +       struct page *page = virt_to_head_page(buf);
> > > > +       struct page *xdp_page;
> > > > +       unsigned int buflen;
> > > > +       struct xdp_buff xdp;
> > > > +       struct sk_buff *skb;
> > > > +       unsigned int delta = 0;
> > > > +       unsigned int metasize = 0;
> > > > +       void *orig_data;
> > > > +       u32 act;
> > > > +
> > > > +       if (unlikely(hdr->hdr.gso_type))
> > > > +               goto err_xdp;
> > > > +
> > > > +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > > +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > > +
> > > > +       if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > > > +               int offset = buf - page_address(page) + header_offset;
> > > > +               unsigned int tlen = len + vi->hdr_len;
> > > > +               int num_buf = 1;
> > > > +
> > > > +               xdp_headroom = virtnet_get_headroom(vi);
> > > > +               header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > > +               headroom = vi->hdr_len + header_offset;
> > > > +               buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > > +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > > +               xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > > > +                                             offset, header_offset,
> > > > +                                             &tlen);
> > > > +               if (!xdp_page)
> > > > +                       goto err_xdp;
> > > > +
> > > > +               buf = page_address(xdp_page);
> > > > +               put_page(page);
> > > > +               page = xdp_page;
> > > > +       }
> > > > +
> > > > +       xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > > > +       xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > > > +                        xdp_headroom, len, true);
> > > > +       orig_data = xdp.data;
> > > > +
> > > > +       act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > > > +
> > > > +       switch (act) {
> > > > +       case XDP_PASS:
> > > > +               /* Recalculate length in case bpf program changed it */
> > > > +               delta = orig_data - xdp.data;
> > > > +               len = xdp.data_end - xdp.data;
> > > > +               metasize = xdp.data - xdp.data_meta;
> > > > +               break;
> > > > +
> > > > +       case XDP_TX:
> > > > +       case XDP_REDIRECT:
> > > > +               goto xdp_xmit;
> > > > +
> > > > +       default:
> > > > +               goto err_xdp;
> > > > +       }
> > > > +
> > > > +       skb = build_skb(buf, buflen);
> > > > +       if (!skb)
> > > > +               goto err;
> > > > +
> > > > +       skb_reserve(skb, headroom - delta);
> > > > +       skb_put(skb, len);
> > > > +       if (metasize)
> > > > +               skb_metadata_set(skb, metasize);
> > > > +
> > > > +       return skb;
> > > > +
> > > > +err_xdp:
> > > > +       stats->xdp_drops++;
> > > > +err:
> > > > +       stats->drops++;
> > > > +       put_page(page);
> > > > +xdp_xmit:
> > > > +       return NULL;
> > > > +}
> > >
> > > It looks like some of the comments of the above version is not addressed?
> > >
> > > "
> > > So we end up with some code duplication between receive_small() and
> > > receive_small_xdp() on building skbs. Is this intended?
> > > "
> >
> > I answer you in the #13 commit of the above version. This patch-set has optimize
> > this with the last two commits. This commit is not unchanged.

For some reason I miss that.

>
> Sorry, typo.
>
> "This commit is unchanged."

Ok.

Acked-by: Jason Wang <jasowang@redhat.com>

Thanks

>
> Thanks.
>
> >
> > Thanks.
> >
> >
> > >
> > > Thanks
> > >
> > > > +
> > > >  static struct sk_buff *receive_small(struct net_device *dev,
> > > >                                      struct virtnet_info *vi,
> > > >                                      struct receive_queue *rq,
> > > > @@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > > >         unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > >                               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > >         struct page *page = virt_to_head_page(buf);
> > > > -       unsigned int delta = 0;
> > > > -       struct page *xdp_page;
> > > > -       unsigned int metasize = 0;
> > > >
> > > >         len -= vi->hdr_len;
> > > >         stats->bytes += len;
> > > > @@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > > >         rcu_read_lock();
> > > >         xdp_prog = rcu_dereference(rq->xdp_prog);
> > > >         if (xdp_prog) {
> > > > -               struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > > > -               struct xdp_buff xdp;
> > > > -               void *orig_data;
> > > > -               u32 act;
> > > > -
> > > > -               if (unlikely(hdr->hdr.gso_type))
> > > > -                       goto err_xdp;
> > > > -
> > > > -               if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > > > -                       int offset = buf - page_address(page) + header_offset;
> > > > -                       unsigned int tlen = len + vi->hdr_len;
> > > > -                       int num_buf = 1;
> > > > -
> > > > -                       xdp_headroom = virtnet_get_headroom(vi);
> > > > -                       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > > -                       headroom = vi->hdr_len + header_offset;
> > > > -                       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > > -                                SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > > -                       xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > > > -                                                     offset, header_offset,
> > > > -                                                     &tlen);
> > > > -                       if (!xdp_page)
> > > > -                               goto err_xdp;
> > > > -
> > > > -                       buf = page_address(xdp_page);
> > > > -                       put_page(page);
> > > > -                       page = xdp_page;
> > > > -               }
> > > > -
> > > > -               xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > > > -               xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > > > -                                xdp_headroom, len, true);
> > > > -               orig_data = xdp.data;
> > > > -
> > > > -               act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > > > -
> > > > -               switch (act) {
> > > > -               case XDP_PASS:
> > > > -                       /* Recalculate length in case bpf program changed it */
> > > > -                       delta = orig_data - xdp.data;
> > > > -                       len = xdp.data_end - xdp.data;
> > > > -                       metasize = xdp.data - xdp.data_meta;
> > > > -                       break;
> > > > -               case XDP_TX:
> > > > -               case XDP_REDIRECT:
> > > > -                       rcu_read_unlock();
> > > > -                       goto xdp_xmit;
> > > > -               default:
> > > > -                       goto err_xdp;
> > > > -               }
> > > > +               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> > > > +                                       len, xdp_xmit, stats);
> > > > +               rcu_read_unlock();
> > > > +               return skb;
> > > >         }
> > > >         rcu_read_unlock();
> > > >
> > > > @@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > > >         skb = build_skb(buf, buflen);
> > > >         if (!skb)
> > > >                 goto err;
> > > > -       skb_reserve(skb, headroom - delta);
> > > > +       skb_reserve(skb, headroom);
> > > >         skb_put(skb, len);
> > > > -       if (!xdp_prog) {
> > > > -               buf += header_offset;
> > > > -               memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > > > -       } /* keep zeroed vnet hdr since XDP is loaded */
> > > > -
> > > > -       if (metasize)
> > > > -               skb_metadata_set(skb, metasize);
> > > >
> > > > +       buf += header_offset;
> > > > +       memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > > >         return skb;
> > > >
> > > > -err_xdp:
> > > > -       rcu_read_unlock();
> > > > -       stats->xdp_drops++;
> > > >  err:
> > > >         stats->drops++;
> > > >         put_page(page);
> > > > -xdp_xmit:
> > > >         return NULL;
> > > >  }
> > > >
> > > > --
> > > > 2.32.0.3.g01195cf9f
> > > >
> > >
>

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp()
@ 2023-04-26  3:19           ` Jason Wang
  0 siblings, 0 replies; 54+ messages in thread
From: Jason Wang @ 2023-04-26  3:19 UTC (permalink / raw)
  To: Xuan Zhuo
  Cc: netdev, Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

On Tue, Apr 25, 2023 at 4:10 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
>
> On Tue, 25 Apr 2023 16:00:05 +0800, Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> > On Tue, 25 Apr 2023 15:58:03 +0800, Jason Wang <jasowang@redhat.com> wrote:
> > > On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> > > >
> > > > The purpose of this patch is to simplify the receive_small().
> > > > Separate all the logic of XDP of small into a function.
> > > >
> > > > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > > ---
> > > >  drivers/net/virtio_net.c | 165 ++++++++++++++++++++++++---------------
> > > >  1 file changed, 100 insertions(+), 65 deletions(-)
> > > >
> > > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > > > index de5a579e8603..9b5fd2e0d27f 100644
> > > > --- a/drivers/net/virtio_net.c
> > > > +++ b/drivers/net/virtio_net.c
> > > > @@ -931,6 +931,99 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
> > > >         return NULL;
> > > >  }
> > > >
> > > > +static struct sk_buff *receive_small_xdp(struct net_device *dev,
> > > > +                                        struct virtnet_info *vi,
> > > > +                                        struct receive_queue *rq,
> > > > +                                        struct bpf_prog *xdp_prog,
> > > > +                                        void *buf,
> > > > +                                        unsigned int xdp_headroom,
> > > > +                                        unsigned int len,
> > > > +                                        unsigned int *xdp_xmit,
> > > > +                                        struct virtnet_rq_stats *stats)
> > > > +{
> > > > +       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > > +       unsigned int headroom = vi->hdr_len + header_offset;
> > > > +       struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > > > +       struct page *page = virt_to_head_page(buf);
> > > > +       struct page *xdp_page;
> > > > +       unsigned int buflen;
> > > > +       struct xdp_buff xdp;
> > > > +       struct sk_buff *skb;
> > > > +       unsigned int delta = 0;
> > > > +       unsigned int metasize = 0;
> > > > +       void *orig_data;
> > > > +       u32 act;
> > > > +
> > > > +       if (unlikely(hdr->hdr.gso_type))
> > > > +               goto err_xdp;
> > > > +
> > > > +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > > +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > > +
> > > > +       if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > > > +               int offset = buf - page_address(page) + header_offset;
> > > > +               unsigned int tlen = len + vi->hdr_len;
> > > > +               int num_buf = 1;
> > > > +
> > > > +               xdp_headroom = virtnet_get_headroom(vi);
> > > > +               header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > > +               headroom = vi->hdr_len + header_offset;
> > > > +               buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > > +                       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > > +               xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > > > +                                             offset, header_offset,
> > > > +                                             &tlen);
> > > > +               if (!xdp_page)
> > > > +                       goto err_xdp;
> > > > +
> > > > +               buf = page_address(xdp_page);
> > > > +               put_page(page);
> > > > +               page = xdp_page;
> > > > +       }
> > > > +
> > > > +       xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > > > +       xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > > > +                        xdp_headroom, len, true);
> > > > +       orig_data = xdp.data;
> > > > +
> > > > +       act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > > > +
> > > > +       switch (act) {
> > > > +       case XDP_PASS:
> > > > +               /* Recalculate length in case bpf program changed it */
> > > > +               delta = orig_data - xdp.data;
> > > > +               len = xdp.data_end - xdp.data;
> > > > +               metasize = xdp.data - xdp.data_meta;
> > > > +               break;
> > > > +
> > > > +       case XDP_TX:
> > > > +       case XDP_REDIRECT:
> > > > +               goto xdp_xmit;
> > > > +
> > > > +       default:
> > > > +               goto err_xdp;
> > > > +       }
> > > > +
> > > > +       skb = build_skb(buf, buflen);
> > > > +       if (!skb)
> > > > +               goto err;
> > > > +
> > > > +       skb_reserve(skb, headroom - delta);
> > > > +       skb_put(skb, len);
> > > > +       if (metasize)
> > > > +               skb_metadata_set(skb, metasize);
> > > > +
> > > > +       return skb;
> > > > +
> > > > +err_xdp:
> > > > +       stats->xdp_drops++;
> > > > +err:
> > > > +       stats->drops++;
> > > > +       put_page(page);
> > > > +xdp_xmit:
> > > > +       return NULL;
> > > > +}
> > >
> > > It looks like some of the comments of the above version is not addressed?
> > >
> > > "
> > > So we end up with some code duplication between receive_small() and
> > > receive_small_xdp() on building skbs. Is this intended?
> > > "
> >
> > I answer you in the #13 commit of the above version. This patch-set has optimize
> > this with the last two commits. This commit is not unchanged.

For some reason I miss that.

>
> Sorry, typo.
>
> "This commit is unchanged."

Ok.

Acked-by: Jason Wang <jasowang@redhat.com>

Thanks

>
> Thanks.
>
> >
> > Thanks.
> >
> >
> > >
> > > Thanks
> > >
> > > > +
> > > >  static struct sk_buff *receive_small(struct net_device *dev,
> > > >                                      struct virtnet_info *vi,
> > > >                                      struct receive_queue *rq,
> > > > @@ -947,9 +1040,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > > >         unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > >                               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > >         struct page *page = virt_to_head_page(buf);
> > > > -       unsigned int delta = 0;
> > > > -       struct page *xdp_page;
> > > > -       unsigned int metasize = 0;
> > > >
> > > >         len -= vi->hdr_len;
> > > >         stats->bytes += len;
> > > > @@ -969,56 +1059,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > > >         rcu_read_lock();
> > > >         xdp_prog = rcu_dereference(rq->xdp_prog);
> > > >         if (xdp_prog) {
> > > > -               struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
> > > > -               struct xdp_buff xdp;
> > > > -               void *orig_data;
> > > > -               u32 act;
> > > > -
> > > > -               if (unlikely(hdr->hdr.gso_type))
> > > > -                       goto err_xdp;
> > > > -
> > > > -               if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
> > > > -                       int offset = buf - page_address(page) + header_offset;
> > > > -                       unsigned int tlen = len + vi->hdr_len;
> > > > -                       int num_buf = 1;
> > > > -
> > > > -                       xdp_headroom = virtnet_get_headroom(vi);
> > > > -                       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > > > -                       headroom = vi->hdr_len + header_offset;
> > > > -                       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > > > -                                SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > > > -                       xdp_page = xdp_linearize_page(rq, &num_buf, page,
> > > > -                                                     offset, header_offset,
> > > > -                                                     &tlen);
> > > > -                       if (!xdp_page)
> > > > -                               goto err_xdp;
> > > > -
> > > > -                       buf = page_address(xdp_page);
> > > > -                       put_page(page);
> > > > -                       page = xdp_page;
> > > > -               }
> > > > -
> > > > -               xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
> > > > -               xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
> > > > -                                xdp_headroom, len, true);
> > > > -               orig_data = xdp.data;
> > > > -
> > > > -               act = virtnet_xdp_handler(xdp_prog, &xdp, dev, xdp_xmit, stats);
> > > > -
> > > > -               switch (act) {
> > > > -               case XDP_PASS:
> > > > -                       /* Recalculate length in case bpf program changed it */
> > > > -                       delta = orig_data - xdp.data;
> > > > -                       len = xdp.data_end - xdp.data;
> > > > -                       metasize = xdp.data - xdp.data_meta;
> > > > -                       break;
> > > > -               case XDP_TX:
> > > > -               case XDP_REDIRECT:
> > > > -                       rcu_read_unlock();
> > > > -                       goto xdp_xmit;
> > > > -               default:
> > > > -                       goto err_xdp;
> > > > -               }
> > > > +               skb = receive_small_xdp(dev, vi, rq, xdp_prog, buf, xdp_headroom,
> > > > +                                       len, xdp_xmit, stats);
> > > > +               rcu_read_unlock();
> > > > +               return skb;
> > > >         }
> > > >         rcu_read_unlock();
> > > >
> > > > @@ -1026,25 +1070,16 @@ static struct sk_buff *receive_small(struct net_device *dev,
> > > >         skb = build_skb(buf, buflen);
> > > >         if (!skb)
> > > >                 goto err;
> > > > -       skb_reserve(skb, headroom - delta);
> > > > +       skb_reserve(skb, headroom);
> > > >         skb_put(skb, len);
> > > > -       if (!xdp_prog) {
> > > > -               buf += header_offset;
> > > > -               memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > > > -       } /* keep zeroed vnet hdr since XDP is loaded */
> > > > -
> > > > -       if (metasize)
> > > > -               skb_metadata_set(skb, metasize);
> > > >
> > > > +       buf += header_offset;
> > > > +       memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
> > > >         return skb;
> > > >
> > > > -err_xdp:
> > > > -       rcu_read_unlock();
> > > > -       stats->xdp_drops++;
> > > >  err:
> > > >         stats->drops++;
> > > >         put_page(page);
> > > > -xdp_xmit:
> > > >         return NULL;
> > > >  }
> > > >
> > > > --
> > > > 2.32.0.3.g01195cf9f
> > > >
> > >
>


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 12/15] virtio_net: small: optimize code
  2023-04-26  3:08     ` Jason Wang
@ 2023-04-26  6:00       ` Xuan Zhuo
  -1 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-26  6:00 UTC (permalink / raw)
  To: Jason Wang
  Cc: netdev, Michael S. Tsirkin, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, virtualization, bpf

On Wed, 26 Apr 2023 11:08:52 +0800, Jason Wang <jasowang@redhat.com> wrote:
> On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >
> > Avoid the problem that some variables(headroom and so on) will repeat
> > the calculation when process xdp.
> >
> > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
>
> Nit: I think we need to tweak the title, it's better to say what is
> optimized. (And it would be better to tweak the title of patch 11 as
> well)

Yes, I agree this.

Thanks.

>
> Acked-by: Jason Wang <jasowang@redhat.com>
>
> > ---
> >  drivers/net/virtio_net.c | 12 ++++++++----
> >  1 file changed, 8 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index 5bc3dca0f60c..601c0e7fc32b 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1031,11 +1031,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         struct sk_buff *skb;
> >         struct bpf_prog *xdp_prog;
> >         unsigned int xdp_headroom = (unsigned long)ctx;
> > -       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > -       unsigned int headroom = vi->hdr_len + header_offset;
> > -       unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > -                             SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> >         struct page *page = virt_to_head_page(buf);
> > +       unsigned int header_offset;
> > +       unsigned int headroom;
> > +       unsigned int buflen;
> >
> >         len -= vi->hdr_len;
> >         stats->bytes += len;
> > @@ -1063,6 +1062,11 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         rcu_read_unlock();
> >
> >  skip_xdp:
> > +       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > +       headroom = vi->hdr_len + header_offset;
> > +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > +
> >         skb = build_skb(buf, buflen);
> >         if (!skb)
> >                 goto err;
> > --
> > 2.32.0.3.g01195cf9f
> >
>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH net-next v3 12/15] virtio_net: small: optimize code
@ 2023-04-26  6:00       ` Xuan Zhuo
  0 siblings, 0 replies; 54+ messages in thread
From: Xuan Zhuo @ 2023-04-26  6:00 UTC (permalink / raw)
  To: Jason Wang
  Cc: Jesper Dangaard Brouer, Daniel Borkmann, Michael S. Tsirkin,
	netdev, John Fastabend, Alexei Starovoitov, virtualization,
	Eric Dumazet, Jakub Kicinski, bpf, Paolo Abeni, David S. Miller

On Wed, 26 Apr 2023 11:08:52 +0800, Jason Wang <jasowang@redhat.com> wrote:
> On Sun, Apr 23, 2023 at 6:58 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote:
> >
> > Avoid the problem that some variables(headroom and so on) will repeat
> > the calculation when process xdp.
> >
> > Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
>
> Nit: I think we need to tweak the title, it's better to say what is
> optimized. (And it would be better to tweak the title of patch 11 as
> well)

Yes, I agree this.

Thanks.

>
> Acked-by: Jason Wang <jasowang@redhat.com>
>
> > ---
> >  drivers/net/virtio_net.c | 12 ++++++++----
> >  1 file changed, 8 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index 5bc3dca0f60c..601c0e7fc32b 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1031,11 +1031,10 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         struct sk_buff *skb;
> >         struct bpf_prog *xdp_prog;
> >         unsigned int xdp_headroom = (unsigned long)ctx;
> > -       unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > -       unsigned int headroom = vi->hdr_len + header_offset;
> > -       unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > -                             SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> >         struct page *page = virt_to_head_page(buf);
> > +       unsigned int header_offset;
> > +       unsigned int headroom;
> > +       unsigned int buflen;
> >
> >         len -= vi->hdr_len;
> >         stats->bytes += len;
> > @@ -1063,6 +1062,11 @@ static struct sk_buff *receive_small(struct net_device *dev,
> >         rcu_read_unlock();
> >
> >  skip_xdp:
> > +       header_offset = VIRTNET_RX_PAD + xdp_headroom;
> > +       headroom = vi->hdr_len + header_offset;
> > +       buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
> > +               SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
> > +
> >         skb = build_skb(buf, buflen);
> >         if (!skb)
> >                 goto err;
> > --
> > 2.32.0.3.g01195cf9f
> >
>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2023-04-26  6:01 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-23 10:57 [PATCH net-next v3 00/15] virtio_net: refactor xdp codes Xuan Zhuo
2023-04-23 10:57 ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 01/15] virtio_net: mergeable xdp: put old page immediately Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 02/15] virtio_net: introduce mergeable_xdp_get_buf() Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 03/15] virtio_net: optimize mergeable_xdp_get_buf() Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 04/15] virtio_net: introduce virtnet_xdp_handler() to seprate the logic of run xdp Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 05/15] virtio_net: separate the logic of freeing xdp shinfo Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 06/15] virtio_net: separate the logic of freeing the rest mergeable buf Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 07/15] virtio_net: auto release xdp shinfo Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-25  7:41   ` Jason Wang
2023-04-25  7:41     ` Jason Wang
2023-04-25  7:46     ` Xuan Zhuo
2023-04-25  7:46       ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 08/15] virtio_net: introduce receive_mergeable_xdp() Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 09/15] virtio_net: merge: remove skip_xdp Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 10/15] virtio_net: introduce receive_small_xdp() Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-25  7:58   ` Jason Wang
2023-04-25  7:58     ` Jason Wang
2023-04-25  8:00     ` Xuan Zhuo
2023-04-25  8:00       ` Xuan Zhuo
2023-04-25  8:09       ` Xuan Zhuo
2023-04-25  8:09         ` Xuan Zhuo
2023-04-26  3:19         ` Jason Wang
2023-04-26  3:19           ` Jason Wang
2023-04-23 10:57 ` [PATCH net-next v3 11/15] virtio_net: small: optimize code Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 12/15] " Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-26  3:08   ` Jason Wang
2023-04-26  3:08     ` Jason Wang
2023-04-26  6:00     ` Xuan Zhuo
2023-04-26  6:00       ` Xuan Zhuo
2023-04-23 10:57 ` [PATCH net-next v3 13/15] virtio_net: small: remove skip_xdp Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-26  3:13   ` Jason Wang
2023-04-26  3:13     ` Jason Wang
2023-04-23 10:57 ` [PATCH net-next v3 14/15] virtio_net: introduce receive_small_build_xdp Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-26  3:15   ` Jason Wang
2023-04-26  3:15     ` Jason Wang
2023-04-23 10:57 ` [PATCH net-next v3 15/15] virtio_net: introduce virtnet_build_skb() Xuan Zhuo
2023-04-23 10:57   ` Xuan Zhuo
2023-04-26  3:16   ` Jason Wang
2023-04-26  3:16     ` Jason Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.