[RFC PATCH 4/8] tests: vhost-vdpa: test SVQ cleanup of pending buffers

Eugenio Pérez posted 8 patches 1 month, 1 week ago
Maintainers: Fabiano Rosas <farosas@suse.de>, Laurent Vivier <lvivier@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
[RFC PATCH 4/8] tests: vhost-vdpa: test SVQ cleanup of pending buffers
Posted by Eugenio Pérez 1 month, 1 week ago
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érez <eperezma@redhat.com>
---
 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=vhost-vdpa,x-svq=on,vhostdev=%s,id=hs0"
 #define VDUSE_RECONNECT_LOG "vduse_reconnect.log"
 
+static int NUM_RX_BUFS = 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;
 
 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);
 }
 
+static void vhost_vdpa_add_rx_pkts(QGuestAllocator *alloc, QVirtioNet *net,
+                                   VdpaThread *t)
+{
+    QTestState *qts = global_qtest;
+
+    t->qemu_mem_to_free = guest_alloc(alloc, 64);
+
+    for (int i = 0; i < NUM_RX_BUFS; i++) {
+        uint32_t head = 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 optionally
  * 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, QGuestAllocator *alloc)
     QVirtioNet *net = obj;
     uint32_t free_head;
 
+    /* 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 = vhost_vdpa_add_tx_pkt_descs(alloc, net, &server->vdpa_thread);
     vhost_vdpa_kick_tx_desc(&server->vdpa_thread, net, free_head);
     vhost_vdpa_get_tx_pkt(alloc, net, free_head, &server->vdpa_thread);
-- 
2.53.0