On 27-05-2025 21:49, Bui Quang Minh wrote:
Currently, in zerocopy mode with mergeable receive buffer, virtio-net
does not support multi buffer but a single buffer only. This commit adds
support for multi mergeable receive buffer in the zerocopy XDP path by
utilizing XDP buffer with frags.

Signed-off-by: Bui Quang Minh <minhquangbu...@gmail.com>
---
  drivers/net/virtio_net.c | 123 +++++++++++++++++++++------------------
  1 file changed, 66 insertions(+), 57 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index e53ba600605a..a9558650f205 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -45,6 +45,8 @@ module_param(napi_tx, bool, 0644);
  #define VIRTIO_XDP_TX         BIT(0)
  #define VIRTIO_XDP_REDIR      BIT(1)
+#define VIRTNET_MAX_ZC_SEGS 8
+
  /* RX packet size EWMA. The average packet size is used to determine the 
packet
   * buffer size when refilling RX rings. As the entire RX ring may be refilled
   * at once, the weight is chosen so that the EWMA will be insensitive to 
short-
@@ -1232,65 +1234,53 @@ static void xsk_drop_follow_bufs(struct net_device *dev,
        }
  }
-static int xsk_append_merge_buffer(struct virtnet_info *vi,
-                                  struct receive_queue *rq,
-                                  struct sk_buff *head_skb,
-                                  u32 num_buf,
-                                  struct virtio_net_hdr_mrg_rxbuf *hdr,
-                                  struct virtnet_rq_stats *stats)
+static int virtnet_build_xsk_buff_mrg(struct virtnet_info *vi,
+                                     struct receive_queue *rq,
+                                     u32 num_buf,
+                                     struct xdp_buff *xdp,
+                                     struct virtnet_rq_stats *stats)
  {
-       struct sk_buff *curr_skb;
-       struct xdp_buff *xdp;
-       u32 len, truesize;
-       struct page *page;
+       unsigned int len;
        void *buf;
- curr_skb = head_skb;
+       if (num_buf < 2)
+               return 0;
+
+       while (num_buf > 1) {
+               struct xdp_buff *new_xdp;
- while (--num_buf) {
                buf = virtqueue_get_buf(rq->vq, &len);
-               if (unlikely(!buf)) {
-                       pr_debug("%s: rx error: %d buffers out of %d missing\n",
-                                vi->dev->name, num_buf,
-                                virtio16_to_cpu(vi->vdev,
-                                                hdr->num_buffers));
+               if (!unlikely(buf)) {

if (unlikely(!buf)) { ?

+                       pr_debug("%s: rx error: %d buffers missing\n",
+                                vi->dev->name, num_buf);
                        DEV_STATS_INC(vi->dev, rx_length_errors);

Thanks,
Alok

Reply via email to