From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202602 header.b=c2QYaVL2; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 9FEDC5A061A for ; Mon, 02 Mar 2026 01:13:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1772410422; bh=JT0BhOwbz+5Zj4LnUU0pBk1JDnyGcR3r44pTl85I+ew=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=c2QYaVL2hu90TfsNK1JYRGBB5LYWHPj8G4liMcax7OGSd/K9PuuSwokkUvwl3t2tE U6Fn1ZH41VI1C+Daz1U43sPrg/8Ptpybfn0isvw4DpLWpKrTHwIvC7+s8BDgy1vyXm Vsv2vM8wTpMhLRs2Pu4yuHpi51Su2FMkpgYbTXwt+xZ99UeF5Hugu0oXJXYHAlXNEs sP00fvi42Vxba9A6rkH6OIIwGUWYoruX70nIfH2T2WuYmLjNe93mDWGk7NkExIGjpw t8gHkLhLleE4KLYwlgNdZ7Rki2y+6+wrApLk1OI8NsItOiihB6EnOhWRftz8uW/zZr Ylp/yGsTwJaVA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4fPKCp4PFCz4wCR; Mon, 02 Mar 2026 11:13:42 +1100 (AEDT) Date: Mon, 2 Mar 2026 11:05:29 +1100 From: David Gibson To: Laurent Vivier Subject: Re: [PATCH 04/12] udp_vu: Move virtqueue management from udp_vu_sock_recv() to its caller Message-ID: References: <20260227140330.2216753-1-lvivier@redhat.com> <20260227140330.2216753-5-lvivier@redhat.com> MIME-Version: 1.0 In-Reply-To: <20260227140330.2216753-5-lvivier@redhat.com> X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="yNqfCYizfDmfLwTh" Content-Disposition: inline Message-ID-Hash: HG6UYV3KT5BY7WH3ESDISAOSV7CEPXDG X-Message-ID-Hash: HG6UYV3KT5BY7WH3ESDISAOSV7CEPXDG X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --yNqfCYizfDmfLwTh Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Feb 27, 2026 at 03:03:22PM +0100, Laurent Vivier wrote: > udp_vu_sock_recv() currently mixes two concerns: receiving data from the > socket and managing virtqueue buffers (collecting, rewinding, releasing). > This makes the function harder to reason about and couples socket I/O > with virtqueue state. >=20 > Move all virtqueue operations, vu_collect(), vu_init_elem(), > vu_queue_rewind(), and the queue-readiness check, into > udp_vu_sock_to_tap(), which is the only caller. This turns > udp_vu_sock_recv() into a pure socket receive function that simply reads > into the provided iov_tail and adjusts its length. >=20 > Signed-off-by: Laurent Vivier Reviewed-by: David Gibson > --- > udp_vu.c | 79 ++++++++++++++++++++++++++------------------------------ > 1 file changed, 37 insertions(+), 42 deletions(-) >=20 > diff --git a/udp_vu.c b/udp_vu.c > index 8f4d0aedac10..aefcab0b86c2 100644 > --- a/udp_vu.c > +++ b/udp_vu.c > @@ -58,75 +58,41 @@ static size_t udp_vu_hdrlen(bool v6) > =20 > /** > * udp_vu_sock_recv() - Receive datagrams from socket into vhost-user bu= ffers > - * @c:=09=09Execution context > * @data:=09IO vector tail for the frame (modified on output) > - * @vq:=09=09virtqueue to use to receive data > * @s:=09=09Socket to receive from > * @v6:=09=09Set for IPv6 connections > * > - * Return: size of received data, 0 if the datagram > - * was discarded because the virtqueue is not ready, -1 on error > + * Return: size of received data, -1 on error > */ > -static ssize_t udp_vu_sock_recv(const struct ctx *c, struct iov_tail *da= ta, > -=09=09=09=09struct vu_virtq *vq, int s, bool v6) > +static ssize_t udp_vu_sock_recv(struct iov_tail *data, int s, bool v6) > { > -=09const struct vu_dev *vdev =3D c->vdev; > -=09struct msghdr msg =3D { 0 }; > +=09struct iovec msg_iov[data->cnt]; > +=09struct msghdr msg =3D { 0 }; > =09struct iov_tail payload; > =09size_t hdrlen; > =09ssize_t dlen; > -=09int iov_cnt; > - > -=09ASSERT(!c->no_udp); > - > -=09if (!vu_queue_enabled(vq) || !vu_queue_started(vq)) { > -=09=09debug("Got UDP packet, but RX virtqueue not usable yet"); > - > -=09=09if (recvmsg(s, &msg, MSG_DONTWAIT) < 0) > -=09=09=09debug_perror("Failed to discard datagram"); > - > -=09=09data->cnt =3D 0; > -=09=09return 0; > -=09} > =20 > =09/* compute L2 header length */ > =09hdrlen =3D udp_vu_hdrlen(v6); > =20 > -=09vu_init_elem(elem, (struct iovec *)data->iov, data->cnt); > - > -=09iov_cnt =3D vu_collect(vdev, vq, elem, ARRAY_SIZE(elem), > -=09=09=09 IP_MAX_MTU + ETH_HLEN + VNET_HLEN, NULL); > -=09if (iov_cnt =3D=3D 0) > -=09=09return -1; > - > -=09data->cnt =3D iov_cnt; > - > =09/* reserve space for the headers */ > =09ASSERT(iov_tail_size(data) >=3D MAX(hdrlen, ETH_ZLEN + VNET_HLEN)); > =20 > =09payload =3D *data; > =09iov_drop_header(&payload, hdrlen); > =20 > -=09struct iovec msg_iov[payload.cnt]; > =09msg.msg_iov =3D msg_iov; > =09msg.msg_iovlen =3D iov_tail_clone(msg.msg_iov, payload.cnt, &payload)= ; > =20 > =09/* read data from the socket */ > =09dlen =3D recvmsg(s, &msg, 0); > -=09if (dlen < 0) { > -=09=09vu_queue_rewind(vq, iov_cnt); > +=09if (dlen < 0) > =09=09return -1; > -=09} > =20 > =09iov_tail_truncate(data, MAX(dlen + hdrlen, ETH_ZLEN + VNET_HLEN)); > =09iov_tail_zero_end(data, dlen + hdrlen); > =09iov_tail_truncate(data, dlen + hdrlen); > =20 > -=09vu_set_vnethdr(vdev, data->iov[0].iov_base, data->cnt); > - > -=09/* release unused buffers */ > -=09vu_queue_rewind(vq, iov_cnt - data->cnt); > - > =09return dlen; > } > =20 > @@ -216,16 +182,45 @@ void udp_vu_sock_to_tap(const struct ctx *c, int s,= int n, flow_sidx_t tosidx) > =09struct iov_tail data; > =09int i; > =20 > +=09ASSERT(!c->no_udp); > + > +=09if (!vu_queue_enabled(vq) || !vu_queue_started(vq)) { > +=09=09struct msghdr msg =3D { 0 }; > + > +=09=09debug("Got UDP packet, but RX virtqueue not usable yet"); > + > +=09=09for (i =3D 0; i < n; i++) { > +=09=09=09if (recvmsg(s, &msg, MSG_DONTWAIT) < 0) > +=09=09=09=09debug_perror("Failed to discard datagram"); > +=09=09} > + > +=09=09return; > +=09} > + > =09for (i =3D 0; i < n; i++) { > =09=09ssize_t dlen; > +=09=09int elem_cnt; > =20 > -=09=09data =3D IOV_TAIL(iov_vu, VIRTQUEUE_MAX_SIZE, 0); > +=09=09vu_init_elem(elem, iov_vu, ARRAY_SIZE(elem)); > =20 > -=09=09dlen =3D udp_vu_sock_recv(c, &data, vq, s, v6); > -=09=09if (dlen < 0) > +=09=09elem_cnt =3D vu_collect(vdev, vq, elem, ARRAY_SIZE(elem), > +=09=09=09=09 IP_MAX_MTU + ETH_HLEN + VNET_HLEN, NULL); > +=09=09if (elem_cnt =3D=3D 0) > =09=09=09break; > =20 > +=09=09data =3D IOV_TAIL(iov_vu, elem_cnt, 0); > + > +=09=09dlen =3D udp_vu_sock_recv(&data, s, v6); > +=09=09if (dlen < 0) { > +=09=09=09vu_queue_rewind(vq, elem_cnt); > +=09=09=09continue; > +=09=09} > + > +=09=09/* release unused buffers */ > +=09=09vu_queue_rewind(vq, elem_cnt - data.cnt); > + > =09=09if (data.cnt > 0) { > +=09=09=09vu_set_vnethdr(vdev, data.iov[0].iov_base, data.cnt); > =09=09=09udp_vu_prepare(c, &data, toside, dlen); > =09=09=09if (*c->pcap) { > =09=09=09=09udp_vu_csum(toside, &data); > --=20 > 2.53.0 >=20 --=20 David Gibson (he or they)=09| I'll have my music baroque, and my code david AT gibson.dropbear.id.au=09| minimalist, thank you, not the other way =09=09=09=09| around. http://www.ozlabs.org/~dgibson --yNqfCYizfDmfLwTh Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmmk1EgACgkQzQJF27ox 2Gd+qw/9FZBqofebrzrdhglhoDmfZlt75yUAD0QHobX3q+Tffib5/frc+JQYmQb1 aRO6vJG/ckyVHI00WncEfBPe0LBr+qHF4dMiofpo3Bai+ncjWU4wy4qdjs8qwocQ 8UAfpl99KZ+gJwn2Nejb5ibX4lsnZszRClI7+i1NNynlLZduyUEpzH97JPqn1ijv 7FeFH2QdRXSCaVVPpGZC2Bf/o+qsCUcYVJ5zyXVSDktihsE+A030klbXb6kdMFIY EL2SsXY9Wl+XuOno7oOAqhcfOerJsmayoVz4rR58PApIRVPx1sJRa0+oLcJZwCCh d+ZLfwx0DHwRiIswjXlCTqF8LSx90xoZs+9R8zhAvT3H7jNMIHDchGuCNL3GEY+t DvN6aaWXPhftLY6mXtJDyLar15c8qwpbTxuaBkw+qLpyX7qeh72ZDUpABS8NW3xP VLaXfTqeO2ZMhMiVXGMvFoFhR+UR1Embq7cpI60qefw98u/KZBWjMsfkLcDda7jy zbkyzyVnVJ2ybYXwx5LSOjGxAbp3k/doTyUy1COgnUBT6gFl4FP7WTO5UYYUzC4L nANlZCmIsFoEnx0CoeTNpFCRmozI1+Tpp81XDdRoKOlbxti9bHT21XxX3ds1iYIw y2996qBRpyN2m7KMXm4HrIYLVXJn/IKYSYE8Jkb14dCH4iz+b0E= =kc6k -----END PGP SIGNATURE----- --yNqfCYizfDmfLwTh--