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=CSrnlJQY; 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 E83915A0262 for ; Wed, 13 May 2026 13:52:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1778673143; 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; bh=DgI7DYqrbjxnNRka5nyGM1vg3AcoEsUCTBMaqTtLkdc=; b=CSrnlJQYLnAbWCY/wp6vvxpDOQr/kF6q1jtY/SzI/23SQIFMt+z8sJjU69P5aHRLq9aXbp 6hC6hKRZ0g0RLnn0016CVr0dSURFyyxexEalCZJvB9RkrwvYHLyR46JHTugoEJDSIdQm4p 5mIsWxizIUbBKdEDerMSEoA7Zogg/TE= 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-367-vOmNdKKaMZy7yB_-5eoIVQ-1; Wed, 13 May 2026 07:52:22 -0400 X-MC-Unique: vOmNdKKaMZy7yB_-5eoIVQ-1 X-Mimecast-MFC-AGG-ID: vOmNdKKaMZy7yB_-5eoIVQ_1778673141 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 943D019560AF for ; Wed, 13 May 2026 11:52:21 +0000 (UTC) Received: from lenovo-t14s.redhat.corp (headnet01.pony-001.prod.iad2.dc.redhat.com [10.2.32.101]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 97BE41955D84; Wed, 13 May 2026 11:52:20 +0000 (UTC) From: Laurent Vivier To: passt-dev@passt.top Subject: [PATCH v4 00/10] vhost-user: Preparatory series for multiple iovec entries per virtqueue element Date: Wed, 13 May 2026 13:52:08 +0200 Message-ID: <20260513115218.1662850-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: GmxvG2F0-Wxk4TkG7j2-nRqohVmAQ8vY65OSYAtf_Bw_1778673141 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Message-ID-Hash: RZVAG5EW7AZU2ERTDAWRCEIPCM7HYUKQ X-Message-ID-Hash: RZVAG5EW7AZU2ERTDAWRCEIPCM7HYUKQ 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, the vhost-user path assumes each virtqueue element contains exactly one iovec entry covering the entire frame. This assumption breaks as some virtio-net drivers (notably iPXE) provide descriptors where the vnet header and the frame payload are in separate buffers, resulting in two iovec entries per virtqueue element. This series refactors the vhost-user data path so that frame lengths, header sizes, and padding are tracked and passed explicitly rather than being derived from iovec sizes. This decoupling is a prerequisite for correctly handling padding of multi-buffer frames. The changes in this series can be split in 3 groups: - New iov helpers (patches 1-2): iov_memset() and iov_memcpy() operate across iovec boundaries. These are needed by the final patch to pad and copy frame data when a frame spans multiple iovec entries. - Structural refactoring (patches 3-5): Move vnethdr setup into vu_flush(), separate virtqueue management from socket I/O in the UDP path, and pass iov arrays explicitly instead of using file-scoped state. These changes make it possible to pass explicit frame lengths through the stack, which is required to pad frames independently of iovec layout. - Explicit length passing throughout the stack (patches 6-10): Thread explicit L4, L2, frame, and data lengths through checksum, pcap, vu_flush(), and tcp_fill_headers(), replacing lengths that were previously derived from iovec sizes. With lengths tracked explicitly, the final patch can centralise Ethernet frame padding into vu_collect() and a new vu_pad() helper that correctly pads frames spanning multiple iovec entries. v4: - rebase - iov_memcpy: use size_t for loop indices i and j - udp_vu: reorder elem[] declaration for inverted christmas tree style - pcap: wrap pcap_iov() declaration and definition to respect line length - write_remainder(): update length parameter description - Add Reviewed-by tags from Jon and David v3: - csum_udp4()/csum_udp6()/udp_vu_csum receive payload length (dlen) rather than l4len - Add a length parameter to write_remainder() and use it in pcap_frame() v2: - Rename iov_memcopy() to iov_memcpy() and use clearer parameter names - Use clearer code in pcap_frame() - Add braces around bodies in pcap.c and tcp_vu.c for style consistency - Extract l2len variable in tap_add_packet() and tcp_vu_send_flag() to avoid repeating the same expression - Fix indentation alignment of iov_skip_bytes() arguments in tcp_vu_c - Introduce fill_size variable in vu_flush() - Reposition comment for ETH_ZLEN in vu_collect() Laurent Vivier (10): iov: Introduce iov_memset() iov: Add iov_memcpy() to copy data between iovec arrays vu_common: Move vnethdr setup into vu_flush() udp_vu: Move virtqueue management from udp_vu_sock_recv() to its caller udp_vu: Pass iov explicitly to helpers instead of using file-scoped array checksum: Pass explicit L4 length to checksum functions pcap: Pass explicit L2 length to pcap_iov() vu_common: Pass explicit frame length to vu_flush() tcp: Pass explicit data length to tcp_fill_headers() vhost-user: Centralise Ethernet frame padding in vu_collect() and vu_pad() checksum.c | 43 +++++++----- checksum.h | 6 +- iov.c | 77 ++++++++++++++++++++++ iov.h | 5 ++ pcap.c | 29 ++++++--- pcap.h | 3 +- tap.c | 10 +-- tcp.c | 14 ++-- tcp_buf.c | 3 +- tcp_internal.h | 2 +- tcp_vu.c | 66 ++++++++++--------- udp.c | 5 +- udp_vu.c | 173 +++++++++++++++++++++++++------------------------ util.c | 31 +++++++-- util.h | 3 +- vu_common.c | 58 ++++++++++------- vu_common.h | 5 +- 17 files changed, 339 insertions(+), 194 deletions(-) -- 2.54.0