Re: [RFC PATCH net-next v2 1/2] virtio-net: support zerocopy multi buffer XDP in mergeable
From: ALOK TIWARI <hidden>
Date: 2025-05-28 16:45:19
Also in:
bpf, lkml, netdev
On 27-05-2025 21:49, Bui Quang Minh wrote:
quoted hunk ↗ jump to hunk
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 <redacted> --- 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