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=JtrbE52y; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by passt.top (Postfix) with ESMTPS id 51D5B5A0265 for ; Fri, 13 Mar 2026 08:21:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773386503; 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=KgQI7hTlc5y/d82k+b96iHnBRKnyul2T4ptQuHXikrE=; b=JtrbE52ySesJ7JWtly0sF5MwUgUg5G79TOzm6RFTSZvOa5ZpfrdUT4rxGWFEqHORLo5F29 eLlwrWkm1EBy3Z1ErzqsjK6DsQiElY/5kHF4aVX0BdQR/qNrld4OGUDluDjb1O7a+gbtBC wDaq/IfnBRbs3z1rDLAxo4qzSTQ+oRA= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-625-wFuvsdSJMRKKpWDcnSVRYQ-1; Fri, 13 Mar 2026 03:21:41 -0400 X-MC-Unique: wFuvsdSJMRKKpWDcnSVRYQ-1 X-Mimecast-MFC-AGG-ID: wFuvsdSJMRKKpWDcnSVRYQ_1773386500 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5D9F1195FDDB for ; Fri, 13 Mar 2026 07:21:40 +0000 (UTC) Received: from lenovo-t14s.redhat.com (unknown [10.44.35.65]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6397519540C2; Fri, 13 Mar 2026 07:21:39 +0000 (UTC) From: Laurent Vivier To: passt-dev@passt.top Subject: [PATCH 1/3] virtio: Pass iovec arrays as separate parameters to vu_queue_pop() Date: Fri, 13 Mar 2026 08:21:34 +0100 Message-ID: <20260313072136.4075535-2-lvivier@redhat.com> In-Reply-To: <20260313072136.4075535-1-lvivier@redhat.com> References: <20260313072136.4075535-1-lvivier@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: DOMEmScs0bATIMmXPSMq2FOOREsKgD6UvuqbRnQUKHQ_1773386500 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true Message-ID-Hash: 5NH4WHCMGGJA65XSQHDC3OVIJSRHVDQU X-Message-ID-Hash: 5NH4WHCMGGJA65XSQHDC3OVIJSRHVDQU X-MailFrom: lvivier@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: Laurent Vivier 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: Currently vu_queue_pop() and vu_queue_map_desc() read the iovec arrays (in_sg/out_sg) and their sizes (in_num/out_num) from the vu_virtq_element struct. This couples the iovec storage to the element, requiring callers like vu_handle_tx() to pre-initialize the element fields before calling vu_queue_pop(). Pass the iovec arrays and their maximum sizes as separate parameters instead. vu_queue_map_desc() now writes the actual descriptor count and iovec pointers back into the element after mapping, rather than using the element as both input and output. This decouples the iovec storage from the element, which is a prerequisite for multi-buffer support where a single frame can span multiple virtqueue elements sharing a common iovec pool. No functional change. Signed-off-by: Laurent Vivier --- virtio.c | 29 ++++++++++++++++++++++------- virtio.h | 4 +++- vu_common.c | 14 +++++++------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/virtio.c b/virtio.c index 447137ee83dd..a671163c27a0 100644 --- a/virtio.c +++ b/virtio.c @@ -428,12 +428,18 @@ static bool virtqueue_map_desc(const struct vu_dev *dev, * @vq: Virtqueue * @idx: First descriptor ring entry to map * @elem: Virtqueue element to store descriptor ring iov + * @in_sg: Incoming iovec array for device-writable descriptors + * @max_in_sg: Maximum number of entries in @in_sg + * @out_sg: Outgoing iovec array for device-readable descriptors + * @max_out_sg: Maximum number of entries in @out_sg * * Return: -1 if there is an error, 0 otherwise */ static int vu_queue_map_desc(const struct vu_dev *dev, struct vu_virtq *vq, unsigned int idx, - struct vu_virtq_element *elem) + struct vu_virtq_element *elem, + struct iovec *in_sg, size_t max_in_sg, + struct iovec *out_sg, size_t max_out_sg) { const struct vring_desc *desc = vq->vring.desc; struct vring_desc desc_buf[VIRTQUEUE_MAX_SIZE]; @@ -470,16 +476,16 @@ static int vu_queue_map_desc(const struct vu_dev *dev, /* Collect all the descriptors */ do { if (le16toh(desc[i].flags) & VRING_DESC_F_WRITE) { - if (!virtqueue_map_desc(dev, &in_num, elem->in_sg, - elem->in_num, + if (!virtqueue_map_desc(dev, &in_num, in_sg, + max_in_sg, le64toh(desc[i].addr), le32toh(desc[i].len))) return -1; } else { if (in_num) die("Incorrect order for descriptors"); - if (!virtqueue_map_desc(dev, &out_num, elem->out_sg, - elem->out_num, + if (!virtqueue_map_desc(dev, &out_num, out_sg, + max_out_sg, le64toh(desc[i].addr), le32toh(desc[i].len))) { return -1; @@ -496,7 +502,9 @@ static int vu_queue_map_desc(const struct vu_dev *dev, die("vhost-user: Failed to read descriptor list"); elem->index = idx; + elem->in_sg = in_sg; elem->in_num = in_num; + elem->out_sg = out_sg; elem->out_num = out_num; return 0; @@ -507,11 +515,17 @@ static int vu_queue_map_desc(const struct vu_dev *dev, * @dev: Vhost-user device * @vq: Virtqueue * @elem: Virtqueue element to fill with the entry information + * @in_sg: Incoming iovec array for device-writable descriptors + * @max_in_sg: Maximum number of entries in @in_sg + * @out_sg: Outgoing iovec array for device-readable descriptors + * @max_out_sg: Maximum number of entries in @out_sg * * Return: -1 if there is an error, 0 otherwise */ int vu_queue_pop(const struct vu_dev *dev, struct vu_virtq *vq, - struct vu_virtq_element *elem) + struct vu_virtq_element *elem, + struct iovec *in_sg, size_t max_in_sg, + struct iovec *out_sg, size_t max_out_sg) { unsigned int head; int ret; @@ -535,7 +549,8 @@ int vu_queue_pop(const struct vu_dev *dev, struct vu_virtq *vq, if (vu_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) vring_set_avail_event(vq, vq->last_avail_idx); - ret = vu_queue_map_desc(dev, vq, head, elem); + ret = vu_queue_map_desc(dev, vq, head, elem, in_sg, max_in_sg, + out_sg, max_out_sg); if (ret < 0) return ret; diff --git a/virtio.h b/virtio.h index d04bbe84e5c4..c7e447d59860 100644 --- a/virtio.h +++ b/virtio.h @@ -188,7 +188,9 @@ static inline bool vu_has_protocol_feature(const struct vu_dev *vdev, void vu_queue_notify(const struct vu_dev *dev, struct vu_virtq *vq); int vu_queue_pop(const struct vu_dev *dev, struct vu_virtq *vq, - struct vu_virtq_element *elem); + struct vu_virtq_element *elem, + struct iovec *in_sg, size_t max_in_sg, + struct iovec *out_sg, size_t max_out_sg); void vu_queue_detach_element(struct vu_virtq *vq); void vu_queue_unpop(struct vu_virtq *vq); bool vu_queue_rewind(struct vu_virtq *vq, unsigned int num); diff --git a/vu_common.c b/vu_common.c index 5f2ce18e5b71..4d809ac38a4b 100644 --- a/vu_common.c +++ b/vu_common.c @@ -91,7 +91,11 @@ int vu_collect(const struct vu_dev *vdev, struct vu_virtq *vq, struct iovec *iov; int ret; - ret = vu_queue_pop(vdev, vq, &elem[elem_cnt]); + ret = vu_queue_pop(vdev, vq, &elem[elem_cnt], + elem[elem_cnt].in_sg, + elem[elem_cnt].in_num, + elem[elem_cnt].out_sg, + elem[elem_cnt].out_num); if (ret < 0) break; @@ -178,12 +182,8 @@ static void vu_handle_tx(struct vu_dev *vdev, int index, int ret; struct iov_tail data; - elem[count].out_num = VU_MAX_TX_BUFFER_NB; - elem[count].out_sg = &out_sg[out_sg_count]; - elem[count].in_num = 0; - elem[count].in_sg = NULL; - - ret = vu_queue_pop(vdev, vq, &elem[count]); + ret = vu_queue_pop(vdev, vq, &elem[count], NULL, 0, + &out_sg[out_sg_count], VU_MAX_TX_BUFFER_NB); if (ret < 0) break; out_sg_count += elem[count].out_num; -- 2.53.0