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>
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,