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