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=202512 header.b=RlXayRn7; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 5470C5A0625 for ; Thu, 08 Jan 2026 00:48:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202512; t=1767829693; bh=2f49q6a4l49WcmO7sqNRug8QLGW+QDMFUVENdUoUPkU=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=RlXayRn7RMktcHILEzEvCfCima07LPuRZFVnvuAyd07yR9wMYawWo+Yr2BDc9nhL3 jqfuKo2RVMI0N45tYxJwUvvqYIYm0N425TQIOmtaACzy5opEbGBXzna4YKIsyV2HA0 8xL7luAfnMW4e99T1NXEtIwd9mMMUGQxStSOpFXxs40qmxtiiSa3AAHZJRBlwhzaUH JW9dvskpCvlx0IVDJ6CQU1QSd/jyqFk0B+zY8Fz4owtnqiXdwp6v9Hf8hsHTKPGD7r P3NV0ypS6eiqMUW/FqCaeLIGaFqWdOMxuZMxm859GMOT0S+0F+dmQqw5MzAg3ST+oE +4befv7YLS7WA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4dml8s0yjYz4wCy; Thu, 08 Jan 2026 10:48:13 +1100 (AEDT) Date: Thu, 8 Jan 2026 10:48:08 +1100 From: David Gibson To: Laurent Vivier Subject: Re: [PATCH v2] udp_vu: Discard datagrams when RX virtqueue is not usable Message-ID: References: <20260107080809.3440007-1-lvivier@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="HFD7QbKruBycSGiz" Content-Disposition: inline In-Reply-To: <20260107080809.3440007-1-lvivier@redhat.com> Message-ID-Hash: A4SIV6I6QIUEFUQSDWZ3RPRJ5VDJWITM X-Message-ID-Hash: A4SIV6I6QIUEFUQSDWZ3RPRJ5VDJWITM 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 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: --HFD7QbKruBycSGiz Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Jan 07, 2026 at 09:08:09AM +0100, Laurent Vivier wrote: > During vhost-user device initialization, UDP datagrams may arrive on > listening sockets before the guest has enabled the RX virtqueue. >=20 > When this happens, udp_vu_sock_recv() returns 0 without consuming > the datagram from the socket. The caller, udp_sock_fwd(), uses a > while loop with udp_peek_addr() to process pending datagrams. Since > the datagram remains in the socket buffer, udp_peek_addr() keeps > returning data available, causing a busy loop with 100% CPU usage. >=20 > To avoid that, we need to discard the data when the virtqueue is not > ready. udp_buf_sock_to_tap() actually does the same as it reads data > with udp_sock_recv() and if fd_tap is not initialized tap_send_frames() > drops them. >=20 > Fixes: 28997fcb29b5 ("vhost-user: add vhost-user") > Link: https://bugs.passt.top/show_bug.cgi?id=3D185 > Signed-off-by: Laurent Vivier Reviewed-by: David Gibson Although one possible nit noted.. > --- >=20 > Notes: > v2: > - move recvmsg() from udp_vu_sock_to_tap() to udp_vu_sock_recv() >=20 > udp_vu.c | 32 ++++++++++++++++++++++---------- > 1 file changed, 22 insertions(+), 10 deletions(-) >=20 > diff --git a/udp_vu.c b/udp_vu.c > index c30dcf97698f..3774d538a2d0 100644 > --- a/udp_vu.c > +++ b/udp_vu.c > @@ -65,7 +65,8 @@ static size_t udp_vu_hdrlen(bool v6) > * @v6: Set for IPv6 connections > * @dlen: Size of received data (output) > * > - * Return: number of iov entries used to store the datagram > + * Return: number of iov entries used to store the datagram, 0 if the da= tagram > + * was discarded because the virtqueue is not ready, -1 on error > */ > static int udp_vu_sock_recv(const struct ctx *c, struct vu_virtq *vq, in= t s, > bool v6, ssize_t *dlen) > @@ -77,6 +78,15 @@ static int udp_vu_sock_recv(const struct ctx *c, struc= t vu_virtq *vq, int s, > =20 > ASSERT(!c->no_udp); > =20 > + if (!vu_queue_enabled(vq) || !vu_queue_started(vq)) { > + debug("Got UDP packet, but RX virtqueue not usable yet"); > + > + if (recvmsg(s, &msg, MSG_DONTWAIT) < 0) You use MSG_DONTWAIT here, but you don't on the normal path. I guess it shouldn't make a difference, since we've come from epoll so we know something is waiting for us. But I think we want to make the paths look as identical as we can from the point of view of the socket side, and this makes it a bit less obvious. > + debug_perror("Failed to discard datagram"); This also isn't really accurate in the case of EAGAIN / EWOULDBLOCK. > + > + return 0; > + } > + > /* compute L2 header length */ > hdrlen =3D udp_vu_hdrlen(v6); > =20 > @@ -87,7 +97,7 @@ static int udp_vu_sock_recv(const struct ctx *c, struct= vu_virtq *vq, int s, > sizeof(struct virtio_net_hdr_mrg_rxbuf), > NULL); > if (iov_cnt =3D=3D 0) > - return 0; > + return -1; > =20 > /* reserve space for the headers */ > ASSERT(iov_vu[0].iov_len >=3D MAX(hdrlen, ETH_ZLEN)); > @@ -101,7 +111,7 @@ static int udp_vu_sock_recv(const struct ctx *c, stru= ct vu_virtq *vq, int s, > *dlen =3D recvmsg(s, &msg, 0); > if (*dlen < 0) { > vu_queue_rewind(vq, iov_cnt); > - return 0; > + return -1; > } > =20 > /* restore the pointer to the headers address */ > @@ -216,15 +226,17 @@ void udp_vu_sock_to_tap(const struct ctx *c, int s,= int n, flow_sidx_t tosidx) > int iov_used; > =20 > iov_used =3D udp_vu_sock_recv(c, vq, s, v6, &dlen); > - if (iov_used <=3D 0) > + if (iov_used < 0) > break; > =20 > - udp_vu_prepare(c, toside, dlen); > - if (*c->pcap) { > - udp_vu_csum(toside, iov_used); > - pcap_iov(iov_vu, iov_used, > - sizeof(struct virtio_net_hdr_mrg_rxbuf)); > + if (iov_used > 0) { > + udp_vu_prepare(c, toside, dlen); > + if (*c->pcap) { > + udp_vu_csum(toside, iov_used); > + pcap_iov(iov_vu, iov_used, > + sizeof(struct virtio_net_hdr_mrg_rxbuf)); > + } > + vu_flush(vdev, vq, elem, iov_used); > } > - vu_flush(vdev, vq, elem, iov_used); > } > } > --=20 > 2.52.0 >=20 --=20 David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson --HFD7QbKruBycSGiz Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmle8LcACgkQzQJF27ox 2Gf0xhAAiyZ6KG56nzflM8soq3BJs5oaP39/hIt4Udd+MdJM4sStaxw0ZMFmVnue PkBiLbwZ5QN1Ztyq3ylG9l+MxeKKlYhmBHhJ3wOnICx+SgdiPqMB8KNmdO3LEQG5 xCF/MPfEgzmk4QD3RQZ9hILXUV8+v6YWnaqfb/pV3ixXt5Im+HjDKpr59vqBYmLq yctqldzk3CTa6u+TvK1pPlKblpZSkO4cMzyOyLT0OYcDQGAeKQuvYhQYOhickVaR VB9AXUu4IY7pdeFPO9xUYbzRF/z1wtOvbfK99Zr7yKMpjqOeYyfCSwe3yW39MBgG r/9yhbMRiFCDQ9RBv8mPXdHmETu9tBt43HcYFleCAiIsDRKHydrL/D6Zcilh1LPC bC2Hnc8glkllNMSLeAKaT+2oMQBnlliGZml+VnqgIKGR9Isk+9jwHJGT6p9E87S4 LHB++VQYCvw5OG5hXLsyAF5yNVV3guxSVPQRfJCWmV3g6ZXXklYHlxT5DtgoT3Fb XVRDXCBoHcHpRVW1ocOlleKX8PZiC5X/5FJV2bgnIZLu6GM3eDzB9pJGIDSkErOn 946OsvjsJoxuBEJbNyKHUXFMUG/NqSKcNF2ir8b/INy7FEI/vJZkcD73kVtLLbWE /JzffLr7PIi24cRs+FsAwcshL1OdqGYrqtboNPZT1tun/ulIVHs= =sW+L -----END PGP SIGNATURE----- --HFD7QbKruBycSGiz--