From nobody Sat Apr 11 21:28:55 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772728836; cv=none; d=zohomail.com; s=zohoarc; b=b/f5PWeSzqo6qhTWQiVqcXh52Z75JaehKSMimD++u0ZYrL9nD7oLibdmuM1qluCR+OltCeM3yurJ/z8KMoyUU+uu8FSkQQc2R6qXV5tFq9ZhakYG18sy/U//PjDAJvZ909rGRZ4ipK5r29LRLwVFkZqGskgcJKeb67wDi5fEmU0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772728836; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=aUU03jfn1S/Xmk+XV/n4eBP9ME+gJywPqDFPRjRBDPs=; b=nMxgNbwY/C3y+ukTQHgfKbsMA8WE5/WzDR7WVuSHrzv5Yg03rP5NzQKmZw/Af49Egbt6TMc5MeiKoW8+a3iO/+aVS53WnCCWV87E6rSDRtVLlfm8GILuOSroUZgIIn0lViQOfVdTlADdi9/fctq0mjP5ofX0H9vDr9GDKkaD0mI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772728836238449.89628866181613; Thu, 5 Mar 2026 08:40:36 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vyBk3-000635-84; Thu, 05 Mar 2026 11:40:03 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBjx-000624-1x for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:39:57 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBjq-0000YF-7k for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:39:56 -0500 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-518-QwNru9kbNF2q5HtF2WaDgQ-1; Thu, 05 Mar 2026 11:39:47 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 D5AD61956054; Thu, 5 Mar 2026 16:39:46 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.34.122]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A625E1958DC5; Thu, 5 Mar 2026 16:39:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772728789; 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=aUU03jfn1S/Xmk+XV/n4eBP9ME+gJywPqDFPRjRBDPs=; b=K+WE7Y66TgrCZVG4SKj4XjxeVkPSN958pD1wnzJOW76uuf0EMCSfGV0BJqeNRYVKlWKjTL 96bT9Z1ei95N+HbWaS++eT421rLsaD0tIQROJgR83txFG2xroXogki3+MyKYOTzhv89GhI j/RGapQxALbAl8XT3uxwBeBuKLkA88c= X-MC-Unique: QwNru9kbNF2q5HtF2WaDgQ-1 X-Mimecast-MFC-AGG-ID: QwNru9kbNF2q5HtF2WaDgQ_1772728787 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: qemu-devel@nongnu.org Cc: Maxime Coquelin , Lei Yang , Paolo Bonzini , "Michael S. Tsirkin" , Stefano Garzarella , Koushik Dutta , Fabiano Rosas , Jason Wang , Laurent Vivier Subject: [RFC PATCH 1/8] tests: vhost-vdpa: add initial VDUSE-based vhost-vdpa tests Date: Thu, 5 Mar 2026 17:39:31 +0100 Message-ID: <20260305163938.3200787-2-eperezma@redhat.com> In-Reply-To: <20260305163938.3200787-1-eperezma@redhat.com> References: <20260305163938.3200787-1-eperezma@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=eperezma@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.892, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.622, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772728839123154100 Based on vhost-user tests, the qos register itself as a VDUSE device and receives the events from QEMU. The test infrastructure creates a thread that acts as a VDUSE device, while the regular test thread is managing QEMU. This basic test just verify that the guest memory ring addresses are accessible, similar to the already existing test in vhost-user. This enables automated testing of vhost-vdpa code paths that previously required manual testing with real hardware. Changes from vhost-user test: * Automatic cleanup of many things. * Handle the vduse fd and timeout. * VDPA device cannot be removed before deleting QEMU, killing QEMU in vhost_vdpa_test_cleanup. * Read in enable callbacks, and the actual test_read_guest_mem is just waiting. * Add vhost_vdpa_thread to abstract fd monitoring * Use QemuMutex and QemuConf for scoped cleanup RFC: I'm not sure if this is the right place to add the tests in meson. Also, a few things are just with asserts() or g_spawn(), instead of more elegant code. Also, I don't know how to include the libvduse.a library as meson complains it's out of the tests/ directory, so I'm including the .c directly. Ugly but it works. Signed-off-by: Eugenio P=C3=A9rez --- tests/qtest/meson.build | 3 + tests/qtest/vhost-vdpa-test.c | 426 ++++++++++++++++++++++++++++++++++ 2 files changed, 429 insertions(+) create mode 100644 tests/qtest/vhost-vdpa-test.c diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index ba9f59d2f8f7..0fdc8fb4a764 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -346,6 +346,9 @@ endif if have_tools and have_vhost_user_blk_server qos_test_ss.add(files('vhost-user-blk-test.c')) endif +if have_libvduse and have_vhost_vdpa + qos_test_ss.add(files('vhost-vdpa-test.c')) +endif =20 tpmemu_files =3D ['tpm-emu.c', 'tpm-util.c', 'tpm-tests.c'] =20 diff --git a/tests/qtest/vhost-vdpa-test.c b/tests/qtest/vhost-vdpa-test.c new file mode 100644 index 000000000000..1fc5acacfed3 --- /dev/null +++ b/tests/qtest/vhost-vdpa-test.c @@ -0,0 +1,426 @@ +/* + * QTest testcase for vhost-vdpa using VDUSE devices + * + * Based on vhost-user-test.c + * Copyright (c) 2014 Virtual Open Systems Sarl. + * Copyright (c) 2026 - VDUSE adaptation + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" + +#include "qemu/lockable.h" + +#include "libqtest-single.h" +#include "qapi/error.h" +#include "libqos/qgraph.h" +#include "hw/virtio/virtio-net.h" + +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_net.h" + +#include "subprojects/libvduse/linux-headers/linux/vduse.h" +#include "subprojects/libvduse/libvduse.h" + +#include +#include +#include +#include + +/* TODO fix this */ +#include "subprojects/libvduse/libvduse.c" + +#define QEMU_CMD_MEM " -m %d -object memory-backend-file,id=3Dmem,size= =3D%dM," \ + "mem-path=3D%s,share=3Don -numa node,memdev=3Dmem" +#define QEMU_CMD_VDPA " -netdev type=3Dvhost-vdpa,vhostdev=3D%s,id=3Dhs0" +#define VDUSE_RECONNECT_LOG "vduse_reconnect.log" + +typedef struct VdpaThread { + GThread *thread; + GMainLoop *loop; + GMainContext *context; +} VdpaThread; + +static void *vhost_vdpa_thread_function(void *data) +{ + GMainLoop *loop =3D data; + g_main_loop_run(loop); + return NULL; +} + +static void vhost_vdpa_thread_init(VdpaThread *t) +{ + t->context =3D g_main_context_new(); + t->loop =3D g_main_loop_new(t->context, FALSE); + t->thread =3D g_thread_new("vdpa-thread", vhost_vdpa_thread_function, = t->loop); +} + +static void vhost_vdpa_thread_cleanup(VdpaThread *t) +{ + g_main_loop_quit(t->loop); + g_thread_join(t->thread); + + while (g_main_context_pending(NULL)) { + g_main_context_iteration(NULL, TRUE); + } + + g_main_loop_unref(t->loop); + g_main_context_unref(t->context); +} + +static void vhost_vdpa_thread_add_source_fd(VdpaThread *t, int fd, + GUnixFDSourceFunc func, void *= data) +{ + GSource *src =3D g_unix_fd_source_new(fd, G_IO_IN); + g_source_set_callback(src, (GSourceFunc)func, data, NULL); + g_source_attach(src, t->context); + g_source_unref(src); +} + +typedef struct TestServer { + gchar *vduse_name; + gchar *vdpa_dev_path; + gchar *tmpfs; + int vq_read_num; + VduseDev *vdev; + VdpaThread vdpa_thread; + QemuMutex data_mutex; + QemuCond data_cond; + bool ready; +} TestServer; + +static bool test_read_first_byte(int dev_fd, uint64_t addr) +{ + struct vduse_iotlb_entry entry; + int fd; + void *mmap_addr; + + entry.start =3D addr; + entry.last =3D addr + 1; + + fd =3D ioctl(dev_fd, VDUSE_IOTLB_GET_FD, &entry); + if (fd < 0) { + g_test_message("Failed to get fd for iova 0x%" PRIx64 ": %s", + addr, strerror(errno)); + return false; + } + + mmap_addr =3D mmap(0, 1, PROT_READ, MAP_SHARED, fd, 0); + if (mmap_addr =3D=3D MAP_FAILED) { + close(fd); + g_test_message("Failed to mmap fd for iova 0x%" PRIx64 ": %s", + addr, strerror(errno)); + goto close_fd; + } + + *(volatile uint8_t *)mmap_addr; + munmap(mmap_addr, 1); + +close_fd: + close(fd); + + return true; +} + +static void vduse_read_guest_mem_enable_queue(VduseDev *dev, VduseVirtq *v= q) +{ + TestServer *s =3D vduse_dev_get_priv(dev); + int dev_fd =3D vduse_dev_get_fd(dev); + struct vduse_vq_info vq_info; + int ret; + + g_test_message("Enabling queue %d", vq->index); + + /* Get VQ info to retrieve ring addresses */ + vq_info.index =3D vq->index; + ret =3D ioctl(dev_fd, VDUSE_VQ_GET_INFO, &vq_info); + if (ret < 0 || !vq_info.ready) { + return; + } + + test_read_first_byte(dev_fd, vq_info.desc_addr); + test_read_first_byte(dev_fd, vq_info.driver_addr); + test_read_first_byte(dev_fd, vq_info.device_addr); + + QEMU_LOCK_GUARD(&s->data_mutex); + s->vq_read_num++; + if (s->vq_read_num =3D=3D 2) { + /* Notify the test that we have read the rings for both queues */ + qemu_cond_broadcast(&s->data_cond); + } +} + +static void vduse_read_guest_mem_disable_queue(VduseDev *dev, VduseVirtq *= vq) +{ + /* Queue disabled */ +} + +static const VduseOps vduse_read_guest_mem_ops =3D { + .enable_queue =3D vduse_read_guest_mem_enable_queue, + .disable_queue =3D vduse_read_guest_mem_disable_queue, +}; + +static gboolean vduse_dev_handler_source_fd(int fd, GIOCondition condition, + void *data) +{ + TestServer *s =3D data; + int r; + + if (poll(&(struct pollfd){.fd =3D fd, .events =3D POLLIN}, 1, 0) <=3D = 0) { + return G_SOURCE_CONTINUE /* Spurious */; + } + + r =3D vduse_dev_handler(s->vdev); + assert (r =3D=3D 0); + return G_SOURCE_CONTINUE; +} + +typedef enum { + VDPA_DEV_ADD, + VDPA_DEV_DEL, +} vdpa_cmd_t; + +/* TODO: Issue proper nl commands */ +static int netlink_vdpa_device_do(vdpa_cmd_t cmd, const char *vduse_name) +{ + g_autoptr(GError) err =3D NULL; + g_auto(GStrv) argv =3D g_strdupv( + (cmd =3D=3D VDPA_DEV_ADD) ? + (char **)(const char *[]){"vdpa", "dev", "add", "name", vduse_= name, + "mgmtdev", "vduse", NULL} : + (char **)(const char *[]){"vdpa", "dev", "del", vduse_name, NU= LL}); + GSpawnFlags flags =3D G_SPAWN_DEFAULT | G_SPAWN_SEARCH_PATH | + G_SPAWN_STDIN_FROM_DEV_NULL | + G_SPAWN_STDOUT_TO_DEV_NULL | + G_SPAWN_STDERR_TO_DEV_NULL; + if (cmd =3D=3D VDPA_DEV_DEL) { + /* TODO: del blocks in read() for the write_err_and_exit, or just = for + * the child to properly close child_err_report_pipe. But, either = way, + * it causes the test to hang if we don't set this flag. + * + * It seems run under gdb step by step also makes the parent able = to + * continue, so probably a race condition? + * + * glib2-devel-2.84.4. + */ + flags |=3D G_SPAWN_LEAVE_DESCRIPTORS_OPEN; + } + gint wait_status =3D 0; + + if (!g_spawn_sync(/* working_dir */ NULL, argv, /* envp */ NULL, flags, + /* child_setup */ NULL, /* user_data */ NULL, + /* standard_output */ NULL, /* standard_error */ NUL= L, + &wait_status, &err)) { + g_test_message("Failed to execute command: %s", err->message); + return -1; + } + + assert(WIFEXITED(wait_status)); + if (WEXITSTATUS(wait_status) !=3D 0) { + g_test_message("Command failed with exit code: %d", + WEXITSTATUS(wait_status)); + return wait_status; + } + + return WEXITSTATUS(wait_status); +} + +static char *vhost_find_device(const char *name) +{ + /* Find vhost-vdpa device name */ + g_autoptr(GDir) dir =3D NULL; + g_autoptr(GError) err =3D NULL; + g_autofree char *sys_path =3D g_strdup_printf("/sys/devices/virtual/vd= use/%s/%s", + name, + name); + dir =3D g_dir_open(sys_path, 0, &err); + if (!dir) { + g_test_message("Failed to open sys path %s: %s", sys_path, err->me= ssage); + return NULL; + } + + for (const char *entry; (entry =3D g_dir_read_name(dir)) !=3D NULL; ) { + if (g_str_has_prefix(entry, "vhost-vdpa-")) { + return g_strdup_printf("/dev/%s", entry); + } + } + + return NULL; +} + +static bool test_setup_reconnect_log(VduseDev *vdev, const char *tmpfs) +{ + g_autofree char *filename =3D NULL; + g_autoptr(GError) err =3D NULL; + int fd, r; + bool ok; + + filename =3D g_build_filename(tmpfs, "vhost-vdpa-test-XXXXXX", NULL); + fd =3D g_mkstemp_full(filename, 0, 0600); + if (fd < 0) { + g_test_message("Failed to create temporary file for reconnect log:= %s", + g_strerror(errno)); + return false; + } + + /* TODO: Properly handle errors here */ + r =3D vduse_set_reconnect_log_file(vdev, filename); + assert(r =3D=3D 0); + r =3D unlink(filename); + assert(r =3D=3D 0); + ok =3D g_close(fd, &err); + assert(ok =3D=3D TRUE); + + return ok; +} + +static TestServer *test_server_new(const gchar *name) +{ + TestServer *server =3D g_new0(TestServer, 1); + g_autoptr(GError) err =3D NULL; + g_autofree char *tmpfs =3D NULL; + char config[sizeof(struct virtio_net_config)] =3D {0}; + uint64_t features; + + vhost_vdpa_thread_init(&server->vdpa_thread); + + server->vduse_name =3D g_strdup_printf("vdpa-test-%s", name); + + qemu_mutex_init(&server->data_mutex); + qemu_cond_init(&server->data_cond); + + features =3D vduse_get_virtio_features() | + (1ULL << VIRTIO_NET_F_MAC); + + server->vdev =3D vduse_dev_create(server->vduse_name, + VIRTIO_ID_NET, + 0x1AF4, /* PCI vendor ID */ + features, + 2, /* num_queues */ + sizeof(config), + config, + &vduse_read_guest_mem_ops, + server); + + if (!server->vdev) { + return server; + } + + vhost_vdpa_thread_add_source_fd(&server->vdpa_thread, server->vdev->fd, + vduse_dev_handler_source_fd, server); + + tmpfs =3D g_dir_make_tmp("vhost-test-XXXXXX", &err); + if (!tmpfs) { + g_test_message("Can't create temporary directory in %s: %s", + g_get_tmp_dir(), err->message); + } + g_assert_nonnull(tmpfs); + server->tmpfs =3D g_steal_pointer(&tmpfs); + + test_setup_reconnect_log(server->vdev, server->tmpfs); + vduse_dev_setup_queue(server->vdev, 0, VIRTQUEUE_MAX_SIZE); + vduse_dev_setup_queue(server->vdev, 1, VIRTQUEUE_MAX_SIZE); + + if (netlink_vdpa_device_do(VDPA_DEV_ADD, server->vduse_name) !=3D 0) { + g_test_message("Failed to add vdpa device"); + return server; + } + server->vdpa_dev_path =3D vhost_find_device(server->vduse_name); + if (!server->vdpa_dev_path) { + return server; + } + + server->ready =3D true; + + return server; +} + +static void test_server_free(TestServer *server) +{ + g_test_message("About to call vdpa del device"); + + netlink_vdpa_device_do(VDPA_DEV_DEL, server->vduse_name); + + /* finish the helper thread and dispatch pending sources */ + vhost_vdpa_thread_cleanup(&server->vdpa_thread); + + if (server->vdev) { + vduse_dev_destroy(server->vdev); + } + + g_free(server->vduse_name); + g_free(server->vdpa_dev_path); + g_free(server->tmpfs); + + qemu_cond_destroy(&server->data_cond); + qemu_mutex_destroy(&server->data_mutex); + g_free(server); +} + +static void wait_for_vqs(TestServer *s) +{ + gint64 end_time_us; + + QEMU_LOCK_GUARD(&s->data_mutex); + end_time_us =3D g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND; + while (s->vq_read_num < 2) { + if (!qemu_cond_timedwait(&s->data_cond, &s->data_mutex, + end_time_us - g_get_monotonic_time())) { + /* timeout has passed */ + g_assert_cmpint(s->vq_read_num, =3D=3D, 2); + break; + } + } +} + +static void vhost_vdpa_test_cleanup(void *s) +{ + TestServer *server =3D s; + + /* Cannot delete vdpa dev until QEMU stops using it. */ + qtest_kill_qemu(global_qtest); + test_server_free(server); +} + +static void *vhost_vdpa_test_setup_memfile(GString *cmd_line, void *arg) +{ + TestServer *server =3D test_server_new("vdpa-memfile"); + + if (!server->ready) { + g_test_skip("Failed to create VDUSE device"); + test_server_free(server); + return NULL; + } + + g_string_append_printf(cmd_line, QEMU_CMD_MEM, 256, 256, server->tmpfs= ); + g_string_append_printf(cmd_line, QEMU_CMD_VDPA, server->vdpa_dev_path); + g_test_message("cmdline: %s", cmd_line->str); + + g_test_queue_destroy(vhost_vdpa_test_cleanup, server); + + return server; +} + +static void test_read_guest_mem(void *obj, void *arg, QGuestAllocator *all= oc) +{ + TestServer *server =3D arg; + + wait_for_vqs(server); +} + +static void register_vhost_vdpa_test(void) +{ + QOSGraphTestOptions opts =3D { + .before =3D vhost_vdpa_test_setup_memfile, + .subprocess =3D true, + .arg =3D NULL, + }; + + qos_add_test("vhost-vdpa/read-guest-mem/memfile", + "virtio-net", + test_read_guest_mem, &opts); +} +libqos_init(register_vhost_vdpa_test); --=20 2.53.0 From nobody Sat Apr 11 21:28:55 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772728897; cv=none; d=zohomail.com; s=zohoarc; b=IuS607S5vMXWEKmN+iIknN+7rfYR6M+4rZy7ZMF/agsq2eTz/HOK7uhXcJ9gfie0SGKqM804985R+9PwAW55Ov62RAQrndBRPRVOvJTF4rgUVe7VR3/0xZiwZzq5mVMFVDNaxVGpny1R9AyEOKPMlBtzAzQtVCnm6owfaOljkdg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772728897; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=xKblfboIEcoo6KaZTrWP7K6ZzZXW+hRgTkfdNeolCmA=; b=faGHdwfIF1Av6vYK55OE25x6mL2e25G4g3IuzqquZyU1dQHrDOyVt3KdMvgzSbSoth2i9b2jeBu5LW3l9E5ysy5cBsELrZ5lwFmsXr3HUyg4WTe2c7X2wrQEcJ6pdHSgFCKGtPMgGU+eh1ebZ5ksQTDZm/rsUX+vWIh7r3NavNE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772728897419896.349265988296; Thu, 5 Mar 2026 08:41:37 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vyBk4-00067Y-Gt; Thu, 05 Mar 2026 11:40:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBjz-00062M-F7 for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:39:59 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBjt-0000YQ-P9 for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:39:57 -0500 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-537-DSR_7XXAOaSRZkACBW2E2Q-1; Thu, 05 Mar 2026 11:39:51 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 A10831956052; Thu, 5 Mar 2026 16:39:50 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.34.122]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7AB5B1958DC5; Thu, 5 Mar 2026 16:39:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772728793; 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=xKblfboIEcoo6KaZTrWP7K6ZzZXW+hRgTkfdNeolCmA=; b=T25WGJ2CazBXTCPpUvv88UDY7KB9h8kqIrp4gKpA+1Oid59QlYb4Bz+Zs6WYkUIglYPcfP 0p6YjEpiFM7lMbyrh0CQOHK+B16ZqLlsbjRmFOE2gAtr9ZI7zn1woX2tVC4SD7PEv1gj7R YB00DnlL7lB4KzD1cFP8zHOX9Il3N1M= X-MC-Unique: DSR_7XXAOaSRZkACBW2E2Q-1 X-Mimecast-MFC-AGG-ID: DSR_7XXAOaSRZkACBW2E2Q_1772728790 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: qemu-devel@nongnu.org Cc: Maxime Coquelin , Lei Yang , Paolo Bonzini , "Michael S. Tsirkin" , Stefano Garzarella , Koushik Dutta , Fabiano Rosas , Jason Wang , Laurent Vivier Subject: [RFC PATCH 2/8] tests: vhost-vdpa: parameterize VDUSE operations Date: Thu, 5 Mar 2026 17:39:32 +0100 Message-ID: <20260305163938.3200787-3-eperezma@redhat.com> In-Reply-To: <20260305163938.3200787-1-eperezma@redhat.com> References: <20260305163938.3200787-1-eperezma@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=eperezma@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.892, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.622, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772728898487158500 Make the VduseOps callbacks a parameter to test_server_new() instead of hardcoding vduse_read_guest_mem_ops. This allows different test cases to provide custom queue enable/disable handlers for testing various vhost-vdpa scenarios. Signed-off-by: Eugenio P=C3=A9rez --- tests/qtest/vhost-vdpa-test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/qtest/vhost-vdpa-test.c b/tests/qtest/vhost-vdpa-test.c index 1fc5acacfed3..1c7d8540bd19 100644 --- a/tests/qtest/vhost-vdpa-test.c +++ b/tests/qtest/vhost-vdpa-test.c @@ -277,7 +277,7 @@ static bool test_setup_reconnect_log(VduseDev *vdev, co= nst char *tmpfs) return ok; } =20 -static TestServer *test_server_new(const gchar *name) +static TestServer *test_server_new(const gchar *name, const VduseOps *ops) { TestServer *server =3D g_new0(TestServer, 1); g_autoptr(GError) err =3D NULL; @@ -302,7 +302,7 @@ static TestServer *test_server_new(const gchar *name) 2, /* num_queues */ sizeof(config), config, - &vduse_read_guest_mem_ops, + ops, server); =20 if (!server->vdev) { @@ -387,7 +387,7 @@ static void vhost_vdpa_test_cleanup(void *s) =20 static void *vhost_vdpa_test_setup_memfile(GString *cmd_line, void *arg) { - TestServer *server =3D test_server_new("vdpa-memfile"); + TestServer *server =3D test_server_new("vdpa-memfile", &vduse_read_gue= st_mem_ops); =20 if (!server->ready) { g_test_skip("Failed to create VDUSE device"); --=20 2.53.0 From nobody Sat Apr 11 21:28:55 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772728875; cv=none; d=zohomail.com; s=zohoarc; b=F5Bcl8pEziYEVdqxl2Nr51S4++W1oQBZuADFihwdQn8nifxDcSvIMJPNAi+2qNKYXliM/s7W+vr7QNNP6MJ9U6JqZgeQZ4c+8oyMIIoVohzc9hv83H1zilP09OC+MBSBsAmtQBU8rfPX4ROWgalil2+geb+l1ATALfvEMFwOJeQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772728875; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=RClAoV8vJf1LhMdcHj1oXtKPcFd7BMQhS6kyWqEjlYg=; b=Y6g/mbrtZ7xILoMt7P9p6K48cxK6G2xc8Xf06V3okMpSiMXdGzacGlZFrUAwUsa05D1FI8n01VsAdcBrhwdEMsMUVQB6xtX4zvVrKpTQ8m4SL/NaZQ6Uaj5aEe0ebgAqGOxhiA+lLCplfdHK9Gnw+tTYK1Ck4JsoqrNFYb3F4Sg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772728875867290.17089392502146; Thu, 5 Mar 2026 08:41:15 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vyBkA-00069m-Ee; Thu, 05 Mar 2026 11:40:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBk3-000638-2J for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:03 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBk1-0000ZZ-CG for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:02 -0500 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-632-BMts5VgUNO6HFA1jUBFRXA-1; Thu, 05 Mar 2026 11:39:58 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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 56CE11956096; Thu, 5 Mar 2026 16:39:54 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.34.122]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 265201958DCA; Thu, 5 Mar 2026 16:39:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772728800; 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=RClAoV8vJf1LhMdcHj1oXtKPcFd7BMQhS6kyWqEjlYg=; b=YOnupyjXct+qv/p6TIUTaX5IZJNq2YOSraCCAs7beUjSjWArq4rSlj4g6hrg8fONxznv04 lfJE6bnFICVKLZLGN2CVk2iyldGzCqb5Il844chQqyR9Tdmln0EThQH+eY+TSc5skb5k5N ec9w/7UossTtTiKLkCbQ7Nb8PgjR1m8= X-MC-Unique: BMts5VgUNO6HFA1jUBFRXA-1 X-Mimecast-MFC-AGG-ID: BMts5VgUNO6HFA1jUBFRXA_1772728794 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: qemu-devel@nongnu.org Cc: Maxime Coquelin , Lei Yang , Paolo Bonzini , "Michael S. Tsirkin" , Stefano Garzarella , Koushik Dutta , Fabiano Rosas , Jason Wang , Laurent Vivier Subject: [RFC PATCH 3/8] tests: vhost-vdpa: add TX packet transmission test Date: Thu, 5 Mar 2026 17:39:33 +0100 Message-ID: <20260305163938.3200787-4-eperezma@redhat.com> In-Reply-To: <20260305163938.3200787-1-eperezma@redhat.com> References: <20260305163938.3200787-1-eperezma@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=eperezma@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.892, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.622, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772728877915154100 Add test infrastructure for sending packets through TX virtqueue. Signed-off-by: Eugenio P=C3=A9rez --- tests/qtest/vhost-vdpa-test.c | 141 +++++++++++++++++++++++++++++++--- 1 file changed, 132 insertions(+), 9 deletions(-) diff --git a/tests/qtest/vhost-vdpa-test.c b/tests/qtest/vhost-vdpa-test.c index 1c7d8540bd19..7b1c34aa415e 100644 --- a/tests/qtest/vhost-vdpa-test.c +++ b/tests/qtest/vhost-vdpa-test.c @@ -17,6 +17,7 @@ #include "libqtest-single.h" #include "qapi/error.h" #include "libqos/qgraph.h" +#include "libqos/virtio-net.h" #include "hw/virtio/virtio-net.h" =20 #include "standard-headers/linux/virtio_ids.h" @@ -25,6 +26,7 @@ #include "subprojects/libvduse/linux-headers/linux/vduse.h" #include "subprojects/libvduse/libvduse.h" =20 +#include #include #include #include @@ -35,7 +37,7 @@ =20 #define QEMU_CMD_MEM " -m %d -object memory-backend-file,id=3Dmem,size= =3D%dM," \ "mem-path=3D%s,share=3Don -numa node,memdev=3Dmem" -#define QEMU_CMD_VDPA " -netdev type=3Dvhost-vdpa,vhostdev=3D%s,id=3Dhs0" +#define QEMU_CMD_VDPA " -netdev type=3Dvhost-vdpa,x-svq=3Don,vhostdev=3D= %s,id=3Dhs0" #define VDUSE_RECONNECT_LOG "vduse_reconnect.log" =20 typedef struct VdpaThread { @@ -80,6 +82,61 @@ static void vhost_vdpa_thread_add_source_fd(VdpaThread *= t, int fd, g_source_unref(src); } =20 +/** + * Send a descriptor or a chain of descriptors to the device, and optional= ly + * and / or update the avail ring and avail_idx of the driver ring. + * + * @alloc: the guest allocator to allocate memory for the descriptors + * @net: the virtio net device + * @t: the vdpa thread to push the expected chain length if kick is true + * + * Returns the kick_id you can use to kick the device in a later call to t= his + * function. + */ +static uint32_t vhost_vdpa_add_tx_pkt_descs(QGuestAllocator *alloc, + QVirtioNet *net, VdpaThread *t) +{ + QTestState *qts =3D global_qtest; + uint32_t req_addr; + + /* TODO: Actually free this. RFC, is actually needed? */ + req_addr =3D guest_alloc(alloc, 64); + g_assert_cmpint(req_addr, >, 0); + + return qvirtqueue_add(qts, net->queues[1], req_addr, 64, /* write */ f= alse, + /* next */ false); +} + +static void vhost_vdpa_kick_tx_desc(VdpaThread *t, QVirtioNet *net, + uint32_t kick_id) +{ + QTestState *qts =3D global_qtest; + + qvirtqueue_kick(qts, net->vdev, net->queues[1], kick_id); +} + +static void vhost_vdpa_get_tx_pkt(QGuestAllocator *alloc, QVirtioNet *net, + uint32_t desc_idx, VdpaThread *t) +{ + g_autofree struct VduseVirtqElement *elem =3D NULL; + int64_t timeout =3D 5 * G_TIME_SPAN_SECOND; + QTestState *qts =3D global_qtest; + vring_desc_t desc; + int64_t end_time_us; + uint32_t len; + + end_time_us =3D g_get_monotonic_time() + timeout; + qvirtio_wait_used_elem(qts, net->vdev, net->queues[1], desc_idx, &len, + timeout); + g_assert_cmpint(g_get_monotonic_time(), <, end_time_us); + g_assert_cmpint(len, =3D=3D, 0); + + qtest_memread(qts, net->queues[1]->desc + sizeof(desc)*desc_idx, &desc, + sizeof(desc)); + /* We know we're version 1 so always little endian */ + guest_free(alloc, le64toh(desc.addr)); +} + typedef struct TestServer { gchar *vduse_name; gchar *vdpa_dev_path; @@ -163,6 +220,54 @@ static const VduseOps vduse_read_guest_mem_ops =3D { .disable_queue =3D vduse_read_guest_mem_disable_queue, }; =20 +static gboolean vhost_vdpa_rxtx_handle_tx(int fd, GIOCondition condition, + void *data) +{ + VduseVirtq *vq =3D data; + + eventfd_read(fd, (eventfd_t[]){0}); + do { + g_autofree VduseVirtqElement *elem =3D NULL; + + elem =3D vduse_queue_pop(vq, sizeof(*elem)); + if (!elem) { + break; + } + + g_test_message("Got element with %d buffers", elem->out_num); + g_assert_cmpint(elem->in_num, =3D=3D, 0); + + vduse_queue_push(vq, elem, 0); + vduse_queue_notify(vq); + } while (true); + + return G_SOURCE_CONTINUE; +} + +static void vduse_rxtx_enable_queue(VduseDev *dev, VduseVirtq *vq) +{ + TestServer *s =3D vduse_dev_get_priv(dev); + + g_test_message("Enabling queue %d", vq->index); + + if (vq->index =3D=3D 1) { + /* This is the tx queue, add a source to handle it */ + vhost_vdpa_thread_add_source_fd(&s->vdpa_thread, + vduse_queue_get_fd(vq), + vhost_vdpa_rxtx_handle_tx, vq); + } +} + +static void vduse_rxtx_disable_queue(VduseDev *dev, VduseVirtq *vq) +{ + /* Queue disabled */ +} + +static const VduseOps vduse_rxtx_ops =3D { + .enable_queue =3D vduse_rxtx_enable_queue, + .disable_queue =3D vduse_rxtx_disable_queue, +}; + static gboolean vduse_dev_handler_source_fd(int fd, GIOCondition condition, void *data) { @@ -292,7 +397,8 @@ static TestServer *test_server_new(const gchar *name, c= onst VduseOps *ops) qemu_mutex_init(&server->data_mutex); qemu_cond_init(&server->data_cond); =20 - features =3D vduse_get_virtio_features() | + /* Disabling NOTIFY_ON_EMPTY as SVQ does not support it */ + features =3D (vduse_get_virtio_features() & ~(1ULL << VIRTIO_F_NOTIFY_= ON_EMPTY)) | (1ULL << VIRTIO_NET_F_MAC); =20 server->vdev =3D vduse_dev_create(server->vduse_name, @@ -376,6 +482,13 @@ static void wait_for_vqs(TestServer *s) } } =20 +static void test_wait(void *obj, void *arg, QGuestAllocator *alloc) +{ + TestServer *server =3D arg; + + wait_for_vqs(server); +} + static void vhost_vdpa_test_cleanup(void *s) { TestServer *server =3D s; @@ -385,9 +498,9 @@ static void vhost_vdpa_test_cleanup(void *s) test_server_free(server); } =20 -static void *vhost_vdpa_test_setup_memfile(GString *cmd_line, void *arg) +static void *vhost_vdpa_test_setup(GString *cmd_line, void *arg) { - TestServer *server =3D test_server_new("vdpa-memfile", &vduse_read_gue= st_mem_ops); + TestServer *server =3D test_server_new("vdpa-memfile", arg); =20 if (!server->ready) { g_test_skip("Failed to create VDUSE device"); @@ -404,23 +517,33 @@ static void *vhost_vdpa_test_setup_memfile(GString *c= md_line, void *arg) return server; } =20 -static void test_read_guest_mem(void *obj, void *arg, QGuestAllocator *all= oc) +static void vhost_vdpa_tx_test(void *obj, void *arg, QGuestAllocator *allo= c) { TestServer *server =3D arg; + QVirtioNet *net =3D obj; + uint32_t free_head; =20 - wait_for_vqs(server); + free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read); + vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head); + vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread); } =20 static void register_vhost_vdpa_test(void) { + /* TODO: void * discards const qualifier */ QOSGraphTestOptions opts =3D { - .before =3D vhost_vdpa_test_setup_memfile, + .before =3D vhost_vdpa_test_setup, .subprocess =3D true, - .arg =3D NULL, + .arg =3D (void *)&vduse_read_guest_mem_ops, }; =20 qos_add_test("vhost-vdpa/read-guest-mem/memfile", "virtio-net", - test_read_guest_mem, &opts); + test_wait, &opts); + + opts.arg =3D (void *)&vduse_rxtx_ops; + qos_add_test("vhost-vdpa/rxtx", + "virtio-net", + vhost_vdpa_tx_test, &opts); } libqos_init(register_vhost_vdpa_test); --=20 2.53.0 From nobody Sat Apr 11 21:28:55 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772728859; cv=none; d=zohomail.com; s=zohoarc; b=RtO/HdURk7nhfi5az5LQuuOKGla0mkOnk9st2g0iOo4ypv+BJom9g0H8w7T7tyGoKOdp+52FfKHMZEvgFC90IaSuede16bfQFmZFHUDq8KbKr9gYuaTdnP0CUdCi2a0rlb7THxEuA3aK8TAlHblAMUlLEtfD+31hal9BEGzLSIY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772728859; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=pH6mnFWB6m5+vxF8G5zIxihji/TxBSSXQlDS/pzqIro=; b=k/OuRHRjen8jjY/cJKUMmhv4rCQkiAFXAG3J3UrjOULpEjcOYRc3MDEapJS/gU8hNajMaDmDS2cDoli10pBpEy5/O0AdVh7hOPJxkNCJg4UP83rfGRLEDebI/xVHOfDYoLNLDirs9iMn5KEzWK1En1nTNOtSS12hkA3zu90ARX8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772728859006339.9862414632536; Thu, 5 Mar 2026 08:40:59 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vyBkA-00069W-DC; Thu, 05 Mar 2026 11:40:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBk4-00067m-E9 for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:04 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBk2-0000an-RC for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:04 -0500 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-653-GRaX9_MHP0aiKvh-zJdH5g-1; Thu, 05 Mar 2026 11:39:58 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 02C341800365; Thu, 5 Mar 2026 16:39:58 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.34.122]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D15941958DC5; Thu, 5 Mar 2026 16:39:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772728802; 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=pH6mnFWB6m5+vxF8G5zIxihji/TxBSSXQlDS/pzqIro=; b=EsBGL2AM2D/QZP+zvlxyR1jynUfh169bU55pD3ofiI7ng4G7Uu7ban8XEUL45PWi4lWqg0 rdAhyFpq3cddB8tVAzYdSWZ4WBQhE7/zMn0r3licDeSppDZyUBhJthMl+nsk5fly3SQMlK dwr5krsYRihCAoH2yh6wPrqPdLjRfGA= X-MC-Unique: GRaX9_MHP0aiKvh-zJdH5g-1 X-Mimecast-MFC-AGG-ID: GRaX9_MHP0aiKvh-zJdH5g_1772728798 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: qemu-devel@nongnu.org Cc: Maxime Coquelin , Lei Yang , Paolo Bonzini , "Michael S. Tsirkin" , Stefano Garzarella , Koushik Dutta , Fabiano Rosas , Jason Wang , Laurent Vivier Subject: [RFC PATCH 4/8] tests: vhost-vdpa: test SVQ cleanup of pending buffers Date: Thu, 5 Mar 2026 17:39:34 +0100 Message-ID: <20260305163938.3200787-5-eperezma@redhat.com> In-Reply-To: <20260305163938.3200787-1-eperezma@redhat.com> References: <20260305163938.3200787-1-eperezma@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=eperezma@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.892, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.622, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772728860602158500 Add RX buffers to the receive queue before terminating QEMU to verify that shadow virtqueue properly cleans up unused descriptors during shutdown. This tests the SVQ teardown path when descriptors remain in the available ring but were never used by the device. Signed-off-by: Eugenio P=C3=A9rez --- tests/qtest/vhost-vdpa-test.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/qtest/vhost-vdpa-test.c b/tests/qtest/vhost-vdpa-test.c index 7b1c34aa415e..8dde7d95b167 100644 --- a/tests/qtest/vhost-vdpa-test.c +++ b/tests/qtest/vhost-vdpa-test.c @@ -40,10 +40,15 @@ #define QEMU_CMD_VDPA " -netdev type=3Dvhost-vdpa,x-svq=3Don,vhostdev=3D= %s,id=3Dhs0" #define VDUSE_RECONNECT_LOG "vduse_reconnect.log" =20 +static int NUM_RX_BUFS =3D 2; + typedef struct VdpaThread { GThread *thread; GMainLoop *loop; GMainContext *context; + + /* Guest memory that must be free at the end of the test */ + uint64_t qemu_mem_to_free; } VdpaThread; =20 static void *vhost_vdpa_thread_function(void *data) @@ -82,6 +87,21 @@ static void vhost_vdpa_thread_add_source_fd(VdpaThread *= t, int fd, g_source_unref(src); } =20 +static void vhost_vdpa_add_rx_pkts(QGuestAllocator *alloc, QVirtioNet *net, + VdpaThread *t) +{ + QTestState *qts =3D global_qtest; + + t->qemu_mem_to_free =3D guest_alloc(alloc, 64); + + for (int i =3D 0; i < NUM_RX_BUFS; i++) { + uint32_t head =3D qvirtqueue_add(qts, net->queues[0], + t->qemu_mem_to_free, 64, + /* write */ false, /* next */ false= ); + qvirtqueue_kick(qts, net->vdev, net->queues[0], head); + } +} + /** * Send a descriptor or a chain of descriptors to the device, and optional= ly * and / or update the avail ring and avail_idx of the driver ring. @@ -523,6 +543,9 @@ static void vhost_vdpa_tx_test(void *obj, void *arg, QG= uestAllocator *alloc) QVirtioNet *net =3D obj; uint32_t free_head; =20 + /* Add some rx packets so SVQ must clean them at the end of QEMU run */ + vhost_vdpa_add_rx_pkts(alloc, net, &server->vdpa_thread); + free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read); vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head); vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread); --=20 2.53.0 From nobody Sat Apr 11 21:28:55 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772728841; cv=none; d=zohomail.com; s=zohoarc; b=ba/871UPAsYc2ZqF462VmOcK4V+yd/i5AN0R0ZHcHJ1U63b3gLeb3/pw4DxMxnntnp9BNLoXyTUB+UeH1mGkI37uHCZcg5aK4ZCXmC7Sx3fAF4aearDUvTaZrPQVkImziysXIKVm2Tofr3sa8EJw+ejV58FoQQeEc1qTeCyNFYU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772728841; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=uOd8J2I5KMMxkHVOYgfkIXRl2cZ0hslmMulWEOLM6Hs=; b=D8sMg0ZIqxNet3hDaM+2xjCj9PuDzzfQaHvaiJZL8G+JoiyFPVio222NcyaoaN9srL+W1ESPUJM9G/kmB2g6Ix4tfjIf9m8w4V2jrg7KEK+uL7wB2HODGDhxkvL0x/JifzrsyTHs1eVtblZZCcnRLW+WC69WUz+Ry6EhZp9CjZ0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772728841200288.30752253877677; Thu, 5 Mar 2026 08:40:41 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vyBkQ-0006As-O7; Thu, 05 Mar 2026 11:40:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBkG-0006AY-41 for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:19 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBk9-0000mF-LN for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:11 -0500 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-362-SbIkhCTaOCijS-_ocvTJlA-1; Thu, 05 Mar 2026 11:40:03 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D49D418005BD; Thu, 5 Mar 2026 16:40:01 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.34.122]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7D7751958DC5; Thu, 5 Mar 2026 16:39:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772728807; 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=uOd8J2I5KMMxkHVOYgfkIXRl2cZ0hslmMulWEOLM6Hs=; b=bRIVQ9VT7BpCF8Mlkkf36Gyol0nvIAjwuC1MyYXqHiQzRR6NsN7NzsvWM8nXElgYli2zBz SBVLINDbgWjYEJIbyKSbQXEpBHIeGsXrPyHqz0GEy+avLlrYJ3pygsj/Pr56vwYsiCW2g8 7BG3VaXruRzR5NZMLDaZHcaaMLI4x3Y= X-MC-Unique: SbIkhCTaOCijS-_ocvTJlA-1 X-Mimecast-MFC-AGG-ID: SbIkhCTaOCijS-_ocvTJlA_1772728802 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: qemu-devel@nongnu.org Cc: Maxime Coquelin , Lei Yang , Paolo Bonzini , "Michael S. Tsirkin" , Stefano Garzarella , Koushik Dutta , Fabiano Rosas , Jason Wang , Laurent Vivier Subject: [RFC PATCH 5/8] tests: vhost-vdpa: add descriptor chain tests Date: Thu, 5 Mar 2026 17:39:35 +0100 Message-ID: <20260305163938.3200787-6-eperezma@redhat.com> In-Reply-To: <20260305163938.3200787-1-eperezma@redhat.com> References: <20260305163938.3200787-1-eperezma@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=eperezma@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.892, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.622, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772728843430154100 Extend TX tests to support multi-descriptor chains: - Add chain_len parameter to control chain length - Use GAsyncQueue to validate expected vs actual chain lengths - Test single descriptors, 2-descriptor chains, and out-of-order chains Chain descriptors all point to the same guest memory buffer to simplify allocation tracking while still testing chain traversal logic. Signed-off-by: Eugenio P=C3=A9rez --- tests/qtest/vhost-vdpa-test.c | 53 ++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/tests/qtest/vhost-vdpa-test.c b/tests/qtest/vhost-vdpa-test.c index 8dde7d95b167..433e5d71ca7a 100644 --- a/tests/qtest/vhost-vdpa-test.c +++ b/tests/qtest/vhost-vdpa-test.c @@ -47,6 +47,9 @@ typedef struct VdpaThread { GMainLoop *loop; GMainContext *context; =20 + /* Expected elements queue to compare properties */ + GAsyncQueue *elem_queue; + /* Guest memory that must be free at the end of the test */ uint64_t qemu_mem_to_free; } VdpaThread; @@ -60,6 +63,7 @@ static void *vhost_vdpa_thread_function(void *data) =20 static void vhost_vdpa_thread_init(VdpaThread *t) { + t->elem_queue =3D g_async_queue_new(); t->context =3D g_main_context_new(); t->loop =3D g_main_loop_new(t->context, FALSE); t->thread =3D g_thread_new("vdpa-thread", vhost_vdpa_thread_function, = t->loop); @@ -76,6 +80,7 @@ static void vhost_vdpa_thread_cleanup(VdpaThread *t) =20 g_main_loop_unref(t->loop); g_main_context_unref(t->context); + g_async_queue_unref(t->elem_queue); } =20 static void vhost_vdpa_thread_add_source_fd(VdpaThread *t, int fd, @@ -109,29 +114,48 @@ static void vhost_vdpa_add_rx_pkts(QGuestAllocator *a= lloc, QVirtioNet *net, * @alloc: the guest allocator to allocate memory for the descriptors * @net: the virtio net device * @t: the vdpa thread to push the expected chain length if kick is true + * @chain_len: the number of descriptors in the chain to add * * Returns the kick_id you can use to kick the device in a later call to t= his * function. */ static uint32_t vhost_vdpa_add_tx_pkt_descs(QGuestAllocator *alloc, - QVirtioNet *net, VdpaThread *t) + QVirtioNet *net, VdpaThread *t, + uint32_t chain_len) { QTestState *qts =3D global_qtest; - uint32_t req_addr; + uint32_t req_addr, kick_id =3D UINT32_MAX; =20 + assert(chain_len > 0); /* TODO: Actually free this. RFC, is actually needed? */ req_addr =3D guest_alloc(alloc, 64); g_assert_cmpint(req_addr, >, 0); =20 - return qvirtqueue_add(qts, net->queues[1], req_addr, 64, /* write */ f= alse, - /* next */ false); + /* + * We set up the descriptors in a way that each of them points to the s= ame + * buffer. This simplifies guest's memory management while still exerci= sing + * chain traversal in SVQ. + */ + for (uint32_t i =3D 0; i < chain_len; i++) { + uint32_t head; + bool next =3D i !=3D chain_len - 1; + + head =3D qvirtqueue_add(qts, net->queues[1], req_addr, 64, + /* write */ false, next); + if (i =3D=3D 0) { + kick_id =3D head; + } + } + + return kick_id; } =20 static void vhost_vdpa_kick_tx_desc(VdpaThread *t, QVirtioNet *net, - uint32_t kick_id) + uint32_t kick_id, uint32_t chain_len) { QTestState *qts =3D global_qtest; =20 + g_async_queue_push(t->elem_queue, (void *)(intptr_t)chain_len); qvirtqueue_kick(qts, net->vdev, net->queues[1], kick_id); } =20 @@ -244,9 +268,12 @@ static gboolean vhost_vdpa_rxtx_handle_tx(int fd, GIOC= ondition condition, void *data) { VduseVirtq *vq =3D data; + VduseDev *dev =3D vduse_queue_get_dev(vq); + TestServer *s =3D vduse_dev_get_priv(dev); =20 eventfd_read(fd, (eventfd_t[]){0}); do { + intptr_t expected_elems; g_autofree VduseVirtqElement *elem =3D NULL; =20 elem =3D vduse_queue_pop(vq, sizeof(*elem)); @@ -254,7 +281,10 @@ static gboolean vhost_vdpa_rxtx_handle_tx(int fd, GIOC= ondition condition, break; } =20 + expected_elems =3D (intptr_t)g_async_queue_try_pop(s->vdpa_thread.= elem_queue); + g_assert_cmpint(expected_elems, >, 0); g_test_message("Got element with %d buffers", elem->out_num); + g_assert_cmpint(elem->out_num, =3D=3D, expected_elems); g_assert_cmpint(elem->in_num, =3D=3D, 0); =20 vduse_queue_push(vq, elem, 0); @@ -546,9 +576,18 @@ static void vhost_vdpa_tx_test(void *obj, void *arg, Q= GuestAllocator *alloc) /* Add some rx packets so SVQ must clean them at the end of QEMU run */ vhost_vdpa_add_rx_pkts(alloc, net, &server->vdpa_thread); =20 - free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read); - vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head); + /* Simple packet */ + free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read, + 1); + vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head, 1); + vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread); + + /* Simple chain */ + free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read, + 2); + vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head, 2); vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread); + } =20 static void register_vhost_vdpa_test(void) --=20 2.53.0 From nobody Sat Apr 11 21:28:55 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772728889; cv=none; d=zohomail.com; s=zohoarc; b=NGy6UJLkEwykgY6dPAiZX22x2ZOOB/WRimB+ro+gVpVevM4t/UsI6AD5dQmJ9+LuFxJ1OWQN4xbO44aaOtwD7xZ4KkP8B5G/K8+9SDgprbcfVTAWOPmPgztZJZjjb4HxiJwMnWnRKlAptgYqZDFfu7KxEfabHb+gC4ulSyN6EF0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772728889; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=top2HucBo65GyFiJ/jhx2kRq7jk2sQkisYHYNcLCT/g=; b=GMmMiwICSxf2fEzmoxEKvZot4R+7uWdKmssdbXvIawyTCGxITJ0RIyRAXO+EAagjU2qT3onp4u4L5IXLCdjsVme0cJklquebBJZgn3/po+AYcIl/tPmvZAUs6SrXNp2yEk/O7VM4acYoujkCRYZLxlkkdV8krqvSZO6NO2uuthk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772728889578446.99948197621677; Thu, 5 Mar 2026 08:41:29 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vyBkn-0006KV-Ie; Thu, 05 Mar 2026 11:40:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBkP-0006Au-E1 for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:26 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBkE-0000mZ-9X for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:18 -0500 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-586-2EkXJe5zPLC9L3zc7-ofmw-1; Thu, 05 Mar 2026 11:40:08 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 816BB1800610; Thu, 5 Mar 2026 16:40:05 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.34.122]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5B72E1958DC7; Thu, 5 Mar 2026 16:40:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772728811; 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=top2HucBo65GyFiJ/jhx2kRq7jk2sQkisYHYNcLCT/g=; b=P3ycasGT/d38y6csAhWGkwhqWLcQQ6wDL9mEUOYmAS4R0WS7q3nbhsyvJNRQw3VWZnFJ4N l1ZequSWbKMFSiKbuJRBCYXWfmd2qzCRhBzp3SlpYsmC0+5pOaWHti1xmvntHbj1OmmeND ZZ9WezLLdzdqz7W8lg3/fkvCZ56B9FA= X-MC-Unique: 2EkXJe5zPLC9L3zc7-ofmw-1 X-Mimecast-MFC-AGG-ID: 2EkXJe5zPLC9L3zc7-ofmw_1772728805 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: qemu-devel@nongnu.org Cc: Maxime Coquelin , Lei Yang , Paolo Bonzini , "Michael S. Tsirkin" , Stefano Garzarella , Koushik Dutta , Fabiano Rosas , Jason Wang , Laurent Vivier Subject: [RFC PATCH 6/8] tests: vhost-vdpa: test out-of-order descriptor completion Date: Thu, 5 Mar 2026 17:39:36 +0100 Message-ID: <20260305163938.3200787-7-eperezma@redhat.com> In-Reply-To: <20260305163938.3200787-1-eperezma@redhat.com> References: <20260305163938.3200787-1-eperezma@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=eperezma@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.892, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.622, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772728890662158500 Add tests that submit descriptors in one order but complete them in a different order: - Submit desc1 then desc2, complete desc2 then desc1 - Same pattern with 2-descriptor chains This verifies SVQ correctly handles devices that don't preserve submission order in completions. Signed-off-by: Eugenio P=C3=A9rez --- tests/qtest/vhost-vdpa-test.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/qtest/vhost-vdpa-test.c b/tests/qtest/vhost-vdpa-test.c index 433e5d71ca7a..5efe688673cb 100644 --- a/tests/qtest/vhost-vdpa-test.c +++ b/tests/qtest/vhost-vdpa-test.c @@ -571,7 +571,7 @@ static void vhost_vdpa_tx_test(void *obj, void *arg, QG= uestAllocator *alloc) { TestServer *server =3D arg; QVirtioNet *net =3D obj; - uint32_t free_head; + uint32_t free_head, free_head2; =20 /* Add some rx packets so SVQ must clean them at the end of QEMU run */ vhost_vdpa_add_rx_pkts(alloc, net, &server->vdpa_thread); @@ -588,6 +588,24 @@ static void vhost_vdpa_tx_test(void *obj, void *arg, Q= GuestAllocator *alloc) vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head, 2); vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread); =20 + /* Out of order descriptors */ + free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read, + 1); + free_head2 =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_t= hread, + 1); + vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head2, 1); + vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head, 1); + + vhost_vdpa_get_tx_pkt(alloc, net, free_head2, &server->vdpa_thread); + vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread); + + /* Out of order chains */ + free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read, + 2); + free_head2 =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_t= hread, + 2); + vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head2, 2); + vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head, 2); } =20 static void register_vhost_vdpa_test(void) --=20 2.53.0 From nobody Sat Apr 11 21:28:55 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772728866; cv=none; d=zohomail.com; s=zohoarc; b=OTjSeK3VIhfiEoR8ZH7UWxhFvGmY0LgGNOw2Vw6tiYkhETbiEfByPzeiVIICoZ0H8yun6xLCE3esflztW0t8XahFUJAKso8V4IPyYWm24/MmXpK8031K8qsVG0uLw4dJa98yLqlKCZWJVXuO+z5RSE0hX7NTibYYB6CUqIO7K0U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772728866; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ylVizt4FBS0JlnoU8wY+GABg+TfM6MLReoF0ERt1lB4=; b=NfLBaIR6/nSrrsR2xx2yT6rFVdss0klx7KNUn3k/NIHzDDBMKgCxZaGfkh8uk2B63RRnc4/BJ/3Dx9y0pUsaiJgsi3EwEhYFzBDdhrQJGn0V6mnGCGSce69/W5Ma0+CAhlyLppvdkUM2G6Hkq/jEh8B/BAwvzuJJCVuKRqRFOL8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1772728866878793.443445235212; Thu, 5 Mar 2026 08:41:06 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vyBkn-0006Iu-8w; Thu, 05 Mar 2026 11:40:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBkQ-0006BC-Uy for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:30 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBkH-0000mk-Jz for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:21 -0500 Received: from mx-prod-mc-03.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-482-Z1WtApBrNYCrp1ygk4mE4Q-1; Thu, 05 Mar 2026 11:40:11 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3040A1955F29; Thu, 5 Mar 2026 16:40:09 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.34.122]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0846D1958DC5; Thu, 5 Mar 2026 16:40:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772728813; 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=ylVizt4FBS0JlnoU8wY+GABg+TfM6MLReoF0ERt1lB4=; b=bMF/MB/uWmSN5wzSxJPalZqXuqFJL4GXZqlZuAb0SY+sSJsiqAFvjGUsGqALmiu9WQSEKX HJvkYG7KCzl9gaKuWQ8dBlLRwdkS+oUGL6aK29ACTM1E0AIJTNzY0SxYcunfRvaytnlLi7 GpyzAsW/m8pi6YSeXCTX0kJ83RZsbOU= X-MC-Unique: Z1WtApBrNYCrp1ygk4mE4Q-1 X-Mimecast-MFC-AGG-ID: Z1WtApBrNYCrp1ygk4mE4Q_1772728809 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: qemu-devel@nongnu.org Cc: Maxime Coquelin , Lei Yang , Paolo Bonzini , "Michael S. Tsirkin" , Stefano Garzarella , Koushik Dutta , Fabiano Rosas , Jason Wang , Laurent Vivier Subject: [RFC PATCH 7/8] tests: vhost-vdpa: introduce TestParameters struct Date: Thu, 5 Mar 2026 17:39:37 +0100 Message-ID: <20260305163938.3200787-8-eperezma@redhat.com> In-Reply-To: <20260305163938.3200787-1-eperezma@redhat.com> References: <20260305163938.3200787-1-eperezma@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=eperezma@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.892, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.622, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772728868147154100 Encapsulate test configuration (VduseOps, features) in TestParameters struct to prepare for parameterized tests with different device feature flags. Signed-off-by: Eugenio P=C3=A9rez --- tests/qtest/vhost-vdpa-test.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/qtest/vhost-vdpa-test.c b/tests/qtest/vhost-vdpa-test.c index 5efe688673cb..0192b00748d5 100644 --- a/tests/qtest/vhost-vdpa-test.c +++ b/tests/qtest/vhost-vdpa-test.c @@ -42,6 +42,10 @@ =20 static int NUM_RX_BUFS =3D 2; =20 +typedef struct TestParameters { + const VduseOps *ops; +} TestParameters; + typedef struct VdpaThread { GThread *thread; GMainLoop *loop; @@ -264,6 +268,10 @@ static const VduseOps vduse_read_guest_mem_ops =3D { .disable_queue =3D vduse_read_guest_mem_disable_queue, }; =20 +static const TestParameters mem_read_params =3D { + .ops =3D &vduse_read_guest_mem_ops, +}; + static gboolean vhost_vdpa_rxtx_handle_tx(int fd, GIOCondition condition, void *data) { @@ -318,6 +326,10 @@ static const VduseOps vduse_rxtx_ops =3D { .disable_queue =3D vduse_rxtx_disable_queue, }; =20 +static const TestParameters rxtx_params =3D { + .ops =3D &vduse_rxtx_ops, +}; + static gboolean vduse_dev_handler_source_fd(int fd, GIOCondition condition, void *data) { @@ -432,7 +444,8 @@ static bool test_setup_reconnect_log(VduseDev *vdev, co= nst char *tmpfs) return ok; } =20 -static TestServer *test_server_new(const gchar *name, const VduseOps *ops) +static TestServer *test_server_new(const gchar *name, + const TestParameters *params) { TestServer *server =3D g_new0(TestServer, 1); g_autoptr(GError) err =3D NULL; @@ -458,7 +471,7 @@ static TestServer *test_server_new(const gchar *name, c= onst VduseOps *ops) 2, /* num_queues */ sizeof(config), config, - ops, + params->ops, server); =20 if (!server->vdev) { @@ -614,14 +627,14 @@ static void register_vhost_vdpa_test(void) QOSGraphTestOptions opts =3D { .before =3D vhost_vdpa_test_setup, .subprocess =3D true, - .arg =3D (void *)&vduse_read_guest_mem_ops, + .arg =3D (void *)&mem_read_params, }; =20 qos_add_test("vhost-vdpa/read-guest-mem/memfile", "virtio-net", test_wait, &opts); =20 - opts.arg =3D (void *)&vduse_rxtx_ops; + opts.arg =3D (void *)&rxtx_params; qos_add_test("vhost-vdpa/rxtx", "virtio-net", vhost_vdpa_tx_test, &opts); --=20 2.53.0 From nobody Sat Apr 11 21:28:55 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1772728890; cv=none; d=zohomail.com; s=zohoarc; b=gTTBdErC9oGp15vEHMUwZ3G0cdANroufswBfRWTCbREz2C0e8BQUmqUh1B15mC7FjDXqwIIvJTcQB9SgLviW/1U6ia+LW/AKl1KlIReXoFrEybl681SKAMaUDYX5Yd7wY9GVbBS15Zql7JSqa4lbKAxRNa/SPYb5nWf2p//k+4w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772728890; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=R59MarovWlomdxjs+pZRDxzIg0jc11eLmA5EOn5Ublw=; b=kWO0SsFtaig1mZ4iZquTw1kzR09tJuKxVoGNT9reBRfRgvl5M2PiRePT+wVEdocTgpb+EqxuiJpJuf6c+TFgKAqPR6VvJHzMEzMzre64VQj2c5z0zeJ4ozprCEnnwApQ713VtKyU3pyuq0gwZxv/hl1fgA8S7lAJ5IQ3zUyVY6Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17727288908771008.8262587541954; Thu, 5 Mar 2026 08:41:30 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vyBks-0006Pk-37; Thu, 05 Mar 2026 11:40:54 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBkU-0006BT-WD for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:32 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vyBkL-0000nl-Ew for qemu-devel@nongnu.org; Thu, 05 Mar 2026 11:40:28 -0500 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-596-9NETlDK9MpWS2KZ7Ncu7kg-1; Thu, 05 Mar 2026 11:40:14 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 18C8D180061D; Thu, 5 Mar 2026 16:40:13 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.34.122]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id AACBD1958DC5; Thu, 5 Mar 2026 16:40:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1772728819; 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=R59MarovWlomdxjs+pZRDxzIg0jc11eLmA5EOn5Ublw=; b=IzBc5IoWXQeM6DYYtAKLxvfOigJUrKRZ8iygGSd5IVB5oGjLz5EzZbaa28m9DivL+xuwde foszlBNT1tt7ghFHg6GxDiuu/th5nZSQdXCrxAT1J8e/f6tV2EC+aXJW5xqj+NVbu8zNzq PtSmKS3gQLluxi8742ZRvzkIG6AuYAQ= X-MC-Unique: 9NETlDK9MpWS2KZ7Ncu7kg-1 X-Mimecast-MFC-AGG-ID: 9NETlDK9MpWS2KZ7Ncu7kg_1772728813 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: qemu-devel@nongnu.org Cc: Maxime Coquelin , Lei Yang , Paolo Bonzini , "Michael S. Tsirkin" , Stefano Garzarella , Koushik Dutta , Fabiano Rosas , Jason Wang , Laurent Vivier Subject: [RFC PATCH 8/8] tests: vhost-vdpa: add VIRTIO_F_IN_ORDER feature tests Date: Thu, 5 Mar 2026 17:39:38 +0100 Message-ID: <20260305163938.3200787-9-eperezma@redhat.com> In-Reply-To: <20260305163938.3200787-1-eperezma@redhat.com> References: <20260305163938.3200787-1-eperezma@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=eperezma@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -5 X-Spam_score: -0.6 X-Spam_bar: / X-Spam_report: (-0.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.892, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.622, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1772728892569158500 The test verifies SVQ correctly handles batched pushes where multiple elements are filled before flushing the used ring. With this test, gcov reported coverage is: Total Hit Lines: 83.9 % 347 291 Functions: 90.3 % 31 28 Branches: 59.2 % 157 93 Apart from impossible banches like scoped cleanups, the missing blocks are: * Event idx. * All SVQ CVQ handling. * Hard to reproduce casuistics like a linear buffer in GPA that is split into more than one buffer in HVA, and then SVQ is saturated. * Buggy input (no descriptors, used descriptors that are not available, moving indexes more than vq size). * Unbinding device call notifier from QEMU vhost system. RFC: I think the tx_packets_inorder struct is also better than the async queue for previous tests. But I'd like to know other people opinions too. Signed-off-by: Eugenio P=C3=A9rez --- tests/qtest/vhost-vdpa-test.c | 183 ++++++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 10 deletions(-) diff --git a/tests/qtest/vhost-vdpa-test.c b/tests/qtest/vhost-vdpa-test.c index 0192b00748d5..99a4df4433e3 100644 --- a/tests/qtest/vhost-vdpa-test.c +++ b/tests/qtest/vhost-vdpa-test.c @@ -44,6 +44,7 @@ static int NUM_RX_BUFS =3D 2; =20 typedef struct TestParameters { const VduseOps *ops; + uint64_t features; } TestParameters; =20 typedef struct VdpaThread { @@ -56,6 +57,9 @@ typedef struct VdpaThread { =20 /* Guest memory that must be free at the end of the test */ uint64_t qemu_mem_to_free; + + /* Expected avail_idx in in_order */ + uint16_t expected_avail_idx; } VdpaThread; =20 static void *vhost_vdpa_thread_function(void *data) @@ -163,8 +167,19 @@ static void vhost_vdpa_kick_tx_desc(VdpaThread *t, QVi= rtioNet *net, qvirtqueue_kick(qts, net->vdev, net->queues[1], kick_id); } =20 +/** + * Get the next used element of the tx queue and check properties of it. If + * wait is true, wait until an element is available, otherwise just check = if + * it's already available. + * + * Note that waiting clean the ISR, so if you call this function with + * wait=3Dtrue, another thread must call the VQ so this call returns. If y= ou + * expect to fetch many descs you need to get subsequent elements with + * wait=3Dfalse. + */ static void vhost_vdpa_get_tx_pkt(QGuestAllocator *alloc, QVirtioNet *net, - uint32_t desc_idx, VdpaThread *t) + uint32_t desc_idx, VdpaThread *t, + bool wait) { g_autofree struct VduseVirtqElement *elem =3D NULL; int64_t timeout =3D 5 * G_TIME_SPAN_SECOND; @@ -174,8 +189,17 @@ static void vhost_vdpa_get_tx_pkt(QGuestAllocator *all= oc, QVirtioNet *net, uint32_t len; =20 end_time_us =3D g_get_monotonic_time() + timeout; - qvirtio_wait_used_elem(qts, net->vdev, net->queues[1], desc_idx, &len, - timeout); + if (wait) { + qvirtio_wait_used_elem(qts, net->vdev, net->queues[1], desc_idx, &= len, + timeout); + } else { + uint32_t got_desc_idx; + + if (!qvirtqueue_get_buf(qts, net->queues[1], &got_desc_idx, &len))= { + g_test_fail(); + } + g_assert_cmpint(got_desc_idx, =3D=3D, desc_idx); + } g_assert_cmpint(g_get_monotonic_time(), <, end_time_us); g_assert_cmpint(len, =3D=3D, 0); =20 @@ -190,6 +214,7 @@ typedef struct TestServer { gchar *vdpa_dev_path; gchar *tmpfs; int vq_read_num; + size_t test_cursor; VduseDev *vdev; VdpaThread vdpa_thread; QemuMutex data_mutex; @@ -330,6 +355,93 @@ static const TestParameters rxtx_params =3D { .ops =3D &vduse_rxtx_ops, }; =20 +static const struct { + uint16_t out_num; + bool push; +} tx_packets_inorder[] =3D { + /* One buffer first */ + { .out_num =3D 1, .push =3D true }, + + /* Then two buffers chained */ + { .out_num =3D 2, .push =3D true }, + + /* Then one buffer, but batch it with the next one */ + { .out_num =3D 1, .push =3D false }, + { .out_num =3D 1, .push =3D true }, + + /* Finally, two buffers chained again, but batch them together */ + { .out_num =3D 2, .push =3D false }, + { .out_num =3D 2, .push =3D true }, +}; + +static gboolean vhost_vdpa_rxtx_inorder_handle_tx(int fd, + GIOCondition condition, + void *data) +{ + VduseVirtq *vq =3D data; + VduseDev *dev =3D vduse_queue_get_dev(vq); + TestServer *s =3D vduse_dev_get_priv(dev); + + eventfd_read(fd, (eventfd_t[]){0}); + do { + g_autofree VduseVirtqElement *elem =3D NULL; + size_t batch_size =3D 1; + elem =3D vduse_queue_pop(vq, sizeof(*elem)); + if (!elem) { + break; + } + + g_assert_cmpint(s->test_cursor, <, G_N_ELEMENTS(tx_packets_inorder= )); + g_assert_cmpint(elem->out_num, =3D=3D, + tx_packets_inorder[s->test_cursor].out_num); + g_assert_cmpint(elem->in_num, =3D=3D, 0); + + if (tx_packets_inorder[s->test_cursor].push) { + for (ssize_t i =3D s->test_cursor - 1; + i >=3D 0 && !tx_packets_inorder[i].push; i--) { + batch_size++; + } + vduse_queue_fill(vq, elem, /* len */ 0, /* offset */ 0); + vduse_queue_flush(vq, batch_size); + vduse_queue_notify(vq); + } + s->test_cursor++; + } while (true); + + return G_SOURCE_CONTINUE; +} + +static void vduse_rxtx_inorder_enable_queue(VduseDev *dev, VduseVirtq *vq) +{ + TestServer *s =3D vduse_dev_get_priv(dev); + + g_test_message("Enabling queue %d", vq->index); + + if (vq->index =3D=3D 1) { + g_assert(dev->features & (1ULL << VIRTIO_F_IN_ORDER)); + + /* This is the tx queue, add a source to handle it */ + vhost_vdpa_thread_add_source_fd(&s->vdpa_thread, + vduse_queue_get_fd(vq), + vhost_vdpa_rxtx_inorder_handle_tx,= vq); + } +} + +static void vduse_rxtx_inorder_disable_queue(VduseDev *dev, VduseVirtq *vq) +{ + /* Queue disabled */ +} + +static const VduseOps vduse_rxtx_inorder_ops =3D { + .enable_queue =3D vduse_rxtx_inorder_enable_queue, + .disable_queue =3D vduse_rxtx_inorder_disable_queue, +}; + +static const TestParameters rxtx_inorder_params =3D { + .ops =3D &vduse_rxtx_inorder_ops, + .features =3D (1ULL << VIRTIO_F_IN_ORDER), +}; + static gboolean vduse_dev_handler_source_fd(int fd, GIOCondition condition, void *data) { @@ -462,7 +574,7 @@ static TestServer *test_server_new(const gchar *name, =20 /* Disabling NOTIFY_ON_EMPTY as SVQ does not support it */ features =3D (vduse_get_virtio_features() & ~(1ULL << VIRTIO_F_NOTIFY_= ON_EMPTY)) | - (1ULL << VIRTIO_NET_F_MAC); + (1ULL << VIRTIO_NET_F_MAC) | params->features; =20 server->vdev =3D vduse_dev_create(server->vduse_name, VIRTIO_ID_NET, @@ -561,7 +673,7 @@ static void vhost_vdpa_test_cleanup(void *s) test_server_free(server); } =20 -static void *vhost_vdpa_test_setup(GString *cmd_line, void *arg) +static void *vhost_vdpa_test_setup0(GString *cmd_line, void *arg) { TestServer *server =3D test_server_new("vdpa-memfile", arg); =20 @@ -580,6 +692,17 @@ static void *vhost_vdpa_test_setup(GString *cmd_line, = void *arg) return server; } =20 +static void *vhost_vdpa_test_setup_inorder(GString *cmd_line, void *arg) +{ + const char *device =3D g_strstr_len(cmd_line->str, -1, + "-device virtio-net-pci"); + g_assert_nonnull(device); + device +=3D strlen("-device virtio-net-pci"); + g_string_insert(cmd_line, device - cmd_line->str, ",in_order=3Don"); + + return vhost_vdpa_test_setup0(cmd_line, arg); +} + static void vhost_vdpa_tx_test(void *obj, void *arg, QGuestAllocator *allo= c) { TestServer *server =3D arg; @@ -593,13 +716,13 @@ static void vhost_vdpa_tx_test(void *obj, void *arg, = QGuestAllocator *alloc) free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read, 1); vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head, 1); - vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread); + vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread, tru= e); =20 /* Simple chain */ free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read, 2); vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head, 2); - vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread); + vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread, tru= e); =20 /* Out of order descriptors */ free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read, @@ -609,8 +732,8 @@ static void vhost_vdpa_tx_test(void *obj, void *arg, QG= uestAllocator *alloc) vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head2, 1); vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head, 1); =20 - vhost_vdpa_get_tx_pkt(alloc, net, free_head2, &server->vdpa_thread); - vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread); + vhost_vdpa_get_tx_pkt(alloc, net, free_head2, &server->vdpa_thread, tr= ue); + vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread, tru= e); =20 /* Out of order chains */ free_head =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_th= read, @@ -621,11 +744,45 @@ static void vhost_vdpa_tx_test(void *obj, void *arg, = QGuestAllocator *alloc) vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head, 2); } =20 +static void vhost_vdpa_tx_inorder_test(void *obj, void *arg, QGuestAllocat= or *alloc) +{ + uint32_t free_head[G_N_ELEMENTS(tx_packets_inorder)]; + TestServer *server =3D arg; + QVirtioNet *net =3D obj; + size_t free_head_idx =3D 0; + + for (size_t i =3D 0; i < G_N_ELEMENTS(tx_packets_inorder); i++) { + uint32_t chain_len =3D tx_packets_inorder[i].out_num; + bool wait =3D true; + + free_head[i] =3D vhost_vdpa_add_tx_pkt_descs(alloc, net, + &server->vdpa_thread, + chain_len); + vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head[i], c= hain_len); + if (!tx_packets_inorder[i].push) { + continue; + } + + /* + * TODO: SVQ uses the emulated VirtIO device underneath so it does= not + * support to batch many used elements in order. This is fragile = and + * could change in the future, and the right solution is to add pr= oper + * support in vhost_vdpa_get_tx_pkt -> qvirtio_wait_used_elem. Le= t's + * just code the current behavior here for now. + */ + for (; free_head_idx <=3D i; free_head_idx++) { + vhost_vdpa_get_tx_pkt(alloc, net, free_head[free_head_idx], + &server->vdpa_thread, wait); + wait =3D false; + } + } +} + static void register_vhost_vdpa_test(void) { /* TODO: void * discards const qualifier */ QOSGraphTestOptions opts =3D { - .before =3D vhost_vdpa_test_setup, + .before =3D vhost_vdpa_test_setup0, .subprocess =3D true, .arg =3D (void *)&mem_read_params, }; @@ -638,5 +795,11 @@ static void register_vhost_vdpa_test(void) qos_add_test("vhost-vdpa/rxtx", "virtio-net", vhost_vdpa_tx_test, &opts); + + opts.before =3D vhost_vdpa_test_setup_inorder; + opts.arg =3D (void *)&rxtx_inorder_params; + qos_add_test("vhost-vdpa/rxtx-inorder", + "virtio-net", + vhost_vdpa_tx_inorder_test, &opts); } libqos_init(register_vhost_vdpa_test); --=20 2.53.0