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>
This commit is contained in:
Stefan Hajnoczi
2026-06-04 16:10:29 -04:00
committed by Michael S. Tsirkin
parent 1ace07171a
commit ef02c6becf

View File

@@ -1487,7 +1487,29 @@ static int vhost_set_vring_file(struct vhost_dev *dev,
static int vhost_user_set_vring_kick(struct vhost_dev *dev,
struct vhost_vring_file *file)
{
return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
int ret = vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
if (ret < 0) {
return ret;
}
/*
* Inject a kick in case the back-end only starts vring processing upon
* receiving a kick. The spec suggests this to improve compatibility.
*/
if (file->fd != -1) {
uint64_t val = 1;
ssize_t nwritten;
do {
nwritten = write(file->fd, &val, sizeof(val));
} while (nwritten < 0 && errno == EINTR);
if (nwritten < 0 && errno != EAGAIN /* back-end can already read */) {
return -errno;
}
}
return 0;
}
static int vhost_user_set_vring_call(struct vhost_dev *dev,