@samitouri / QOSamiQemu / commits / ef02c6becf

vhost-user: inject kick after SET_VRING_KICK

The vhost-user specification was updated to say that front-ends should inject a kick after SET_VRING_KICK in case the back-end implements the old spec wording which said vrings start when a kick is received. Do this in QEMU's front-end. An example scenario where this behavior helps: the back-end fails to check if the vring has available buffers when SET_VRING_KICK is received and the front-end stopped and then restarted the vring. In the case the back-end may not notice the available buffers unless the front-end injects a kick. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20260604201029.250450-4-stefanha@redhat.com>

Stefan Hajnoczi committed Jun 4, 2026 at 16:10 UTC ef02c6becfb1383bb50f7cf724f77a9bccf17bdd
1 file changed +23 -1
hw/virtio/vhost-user.c
+23 -1
@@ -1487,7 +1487,29 @@ static int vhost_set_vring_file(struct vhost_dev *dev,
1487 static int vhost_user_set_vring_kick(struct vhost_dev *dev,
1488 struct vhost_vring_file *file)
1489 {
1490 - return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
1490 + int ret = vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
1491 + if (ret < 0) {
1492 + return ret;
1493 + }
1494 +
1495 + /*
1496 + * Inject a kick in case the back-end only starts vring processing upon
1497 + * receiving a kick. The spec suggests this to improve compatibility.
1498 + */
1499 + if (file->fd != -1) {
1500 + uint64_t val = 1;
1501 + ssize_t nwritten;
1502 +
1503 + do {
1504 + nwritten = write(file->fd, &val, sizeof(val));
1505 + } while (nwritten < 0 && errno == EINTR);
1506 +
1507 + if (nwritten < 0 && errno != EAGAIN /* back-end can already read */) {
1508 + return -errno;
1509 + }
1510 + }
1511 +
1512 + return 0;
1513 }
1514
1515 static int vhost_user_set_vring_call(struct vhost_dev *dev,