From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=N2Tj9zr/; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by passt.top (Postfix) with ESMTPS id C62DC5A0265 for ; Fri, 03 Apr 2026 13:53:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775217212; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9TFhICoo/oslNy6/zUe3Mm7waxCUvc0+aDQDJwRzj6M=; b=N2Tj9zr/MZvZCuCJg0f8A10ItuKDdEuGgLVOYTR/z0+jzJHP6ODSCjj38rogvo6mN2uWEh YnF/oppKnVzkES0bsQNrIf3L12siAaHsdKAVwVhuIxXz7j1/z3eU0d42X4pH6hSeHA/3r9 V1+Fk7XPheYzdea7mcYlTKlbcR0+1yE= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-152-a3YDuCDdMbuX5a1XKtEa_Q-1; Fri, 03 Apr 2026 07:53:30 -0400 X-MC-Unique: a3YDuCDdMbuX5a1XKtEa_Q-1 X-Mimecast-MFC-AGG-ID: a3YDuCDdMbuX5a1XKtEa_Q_1775217209 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-43d03db814eso1922976f8f.2 for ; Fri, 03 Apr 2026 04:53:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775217208; x=1775822008; h=date:content-transfer-encoding:mime-version:organization:references :in-reply-to:message-id:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9TFhICoo/oslNy6/zUe3Mm7waxCUvc0+aDQDJwRzj6M=; b=DdIAfhng5gxDhRF7wO6YSVtRZGxkiFcukJOUO7ObRpT4oj6fEytj0X/H+ckXOkou7T +6t65JXGSpzpJIsAlqCbzxNEQ/6tz4HCdez9wQHxHX3yan9VoBojXaiNdFjplXbYkE3v 0mWApKXJBfdhG6R4KkzE6xH66ftr4b5pLzvoSC5R48A8cNTN8jXo2/ZcVFOHFRcwMl/1 3ofpH3PlGTckZdAiCUoi6gqTOLGT0pysH5AKxkEzMGJ7oC4TVbAdZLIh0/cupnsZIZJY CDc3dzYNXOTE1ddo3h5xZXTROb64k+xGtOd0IYrni18AEPgXEA0S/TWKzW19C7qDixbU xKcQ== X-Gm-Message-State: AOJu0Yx4VNIbUs9wqLYuTsHFE0HKkei8JXtMe3PW+Z/jdIIel6nU7otV ksepE2lMv41BsZ5dFYKLnAZNjHjrqQ7to29OLZNLeLkAmRpS99KXDGAsU+Ar/c4k0Z+dX76TCmV /lFNTv2IcVNyYfbfxnG7zTswc6jEI0GLGPTePbXOu+7TlODs5uhkfTfJ76jYAAJY5dviM0CWozC bfGCpQ93rn0+n0HO8YvukTesdTNotQrNLTfiXg X-Gm-Gg: AeBDies2RgEmhuhD5jMzshobXqZALCMsWmTrkNrAQj80H8Q1tW4cNPFR+kbgoVCpNqb swgE658r1Q5M4PZt0Vb/rG+il7fIRBsRkq8fPg+I2tXGAX6YcLBXWFvmFx5CXPpQ1Eu3/4BZBNb 9bE+THr0hKIxrHmf33xjw8FXUx60CDZHl4lMW9ZToOtJXOIqfbClq9BIwhK0kG27/XyGDXbmY2u w+Y9ciG3b82R8vTxIuaWc9cRke/8ete2Flv7c9y95Qhf/FcCbWEBGfrJRBaxzH/xVmQW7bzBH3a aJD4ZmMb1kXiOPIMFdeAL3qYlUFOEtbuc4vTXduNfQKD53WSqmE1FPv1CEYNS/rgfYTTZqFQV5O KTHT6/DeCKntZYvLdkIj8rQQDNk5dn+BigORihlLrJHeYELw8nw== X-Received: by 2002:a05:6000:1acf:b0:43c:f81f:3e7d with SMTP id ffacd0b85a97d-43d29280fc5mr4422885f8f.4.1775217207607; Fri, 03 Apr 2026 04:53:27 -0700 (PDT) X-Received: by 2002:a05:6000:1acf:b0:43c:f81f:3e7d with SMTP id ffacd0b85a97d-43d29280fc5mr4422825f8f.4.1775217206984; Fri, 03 Apr 2026 04:53:26 -0700 (PDT) Received: from maya.myfinge.rs (ifcgrfdd.trafficplex.cloud. [176.103.220.4]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43d1e4d2738sm16330556f8f.24.2026.04.03.04.53.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 04:53:26 -0700 (PDT) From: Stefano Brivio To: Laurent Vivier Subject: Re: [PATCH v6 1/3] udp_vu: Allow virtqueue elements with multiple iovec entries Message-ID: <20260403135309.1d84f5dd@elisabeth> In-Reply-To: <20260401192326.1783350-2-lvivier@redhat.com> References: <20260401192326.1783350-1-lvivier@redhat.com> <20260401192326.1783350-2-lvivier@redhat.com> Organization: Red Hat X-Mailer: Claws Mail 4.2.0 (GTK 3.24.49; x86_64-pc-linux-gnu) MIME-Version: 1.0 Date: Fri, 03 Apr 2026 13:53:23 +0200 (CEST) X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: lFBI-hIUDY4-SC4yn2idTZkHaGxdqHd-Eaf5mdthL6o_1775217209 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Message-ID-Hash: CEQG5TVPMDJBY3YO62TNFSTLZMYIWKHI X-Message-ID-Hash: CEQG5TVPMDJBY3YO62TNFSTLZMYIWKHI X-MailFrom: sbrivio@redhat.com 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: On Wed, 1 Apr 2026 21:23:24 +0200 Laurent Vivier wrote: > The previous code assumed a 1:1 mapping between virtqueue elements and > iovec entries (enforced by an assert). Drop that assumption to allow > elements that span multiple iovecs: track elem_used separately by > walking the element list against the iov count returned after padding. > This also fixes vu_queue_rewind() and vu_flush() to use the element > count rather than the iov count. > > Use iov_tail_clone() in udp_vu_sock_recv() to handle header offset, > replacing the manual base/len adjustment and restore pattern. > > Signed-off-by: Laurent Vivier > --- > udp_vu.c | 29 ++++++++++++++--------------- > 1 file changed, 14 insertions(+), 15 deletions(-) > > diff --git a/udp_vu.c b/udp_vu.c > index 30af64034516..5608a3a96ff5 100644 > --- a/udp_vu.c > +++ b/udp_vu.c > @@ -64,30 +64,25 @@ static size_t udp_vu_hdrlen(bool v6) > */ > static ssize_t udp_vu_sock_recv(struct iovec *iov, size_t *cnt, int s, bool v6) > { > + struct iovec msg_iov[*cnt]; Variable-length Arrays (VLAs) are allowed starting from C99 but we should really really avoid them. If 'cnt' is big enough, we risk writing all over the place. That's the main reason why they were more or less banned from the Linux kernel some years ago and eventually eradicated: https://lore.kernel.org/lkml/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com/ https://lore.kernel.org/lkml/20181028172401.GA41102@beast/ Can we use VIRTQUEUE_MAX_SIZE as upper bound like udp_vu_sock_to_tap() does? We should probably add -Wvla by the way. > struct msghdr msg = { 0 }; > + struct iov_tail payload; > size_t hdrlen, iov_used; > ssize_t dlen; > > /* compute L2 header length */ > hdrlen = udp_vu_hdrlen(v6); > > - /* reserve space for the headers */ > - assert(iov[0].iov_len >= MAX(hdrlen, ETH_ZLEN + VNET_HLEN)); > - iov[0].iov_base = (char *)iov[0].iov_base + hdrlen; > - iov[0].iov_len -= hdrlen; > + payload = IOV_TAIL(iov, *cnt, hdrlen); > > - /* read data from the socket */ > - msg.msg_iov = iov; > - msg.msg_iovlen = *cnt; > + msg.msg_iov = msg_iov; > + msg.msg_iovlen = iov_tail_clone(msg.msg_iov, payload.cnt, &payload); > > + /* read data from the socket */ > dlen = recvmsg(s, &msg, 0); > if (dlen < 0) > return -1; > > - /* restore the pointer to the headers address */ > - iov[0].iov_base = (char *)iov[0].iov_base - hdrlen; > - iov[0].iov_len += hdrlen; > - > iov_used = iov_skip_bytes(iov, *cnt, > MAX(dlen + hdrlen, VNET_HLEN + ETH_ZLEN), > NULL); > @@ -205,7 +200,7 @@ void udp_vu_sock_to_tap(const struct ctx *c, int s, int n, flow_sidx_t tosidx) > } > > for (i = 0; i < n; i++) { > - unsigned elem_cnt, elem_used; > + unsigned elem_cnt, elem_used, j, k; > size_t iov_cnt; > ssize_t dlen; > > @@ -215,15 +210,19 @@ void udp_vu_sock_to_tap(const struct ctx *c, int s, int n, flow_sidx_t tosidx) > if (elem_cnt == 0) > break; > > - assert((size_t)elem_cnt == iov_cnt); /* one iovec per element */ > - > dlen = udp_vu_sock_recv(iov_vu, &iov_cnt, s, v6); > if (dlen < 0) { > vu_queue_rewind(vq, elem_cnt); > break; > } > > - elem_used = iov_cnt; /* one iovec per element */ > + elem_used = 0; > + for (j = 0, k = 0; k < iov_cnt && j < elem_cnt; j++) { > + if (k + elem[j].in_num > iov_cnt) > + elem[j].in_num = iov_cnt - k; I think it would be more intuitive to write it like this: size_t iov_still_needed = iov_cnt - k; if (elem[j].in_num > iov_still_needed) elem[j].in_num = iov_still_needed; ...otherwise it looks like 'k + elem[j].in_num' needs to satisfy some kind of bound, but that's not the case. > + k += elem[j].in_num; > + elem_used++; > + } > > /* release unused buffers */ > vu_queue_rewind(vq, elem_cnt - elem_used); -- Stefano