libvhost-user: look for available vq buffers upon SET_VRING_KICK

When a vring is started the back-end must look for available vq buffers
and process them. This scenario can happen if the back-end is stopped
with unprocessed available buffers and then started again.

The inflight I/O tracking code already did this, but it should also be
done when inflight I/O tracking is not enabled.

Move the code and make it robust in case of EINTR or EAGAIN.

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-3-stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2026-06-04 16:10:28 -04:00
committed by Michael S. Tsirkin
parent 37b14d86d6
commit 1ace07171a

View File

@@ -1390,11 +1390,6 @@ vu_check_queue_inflights(VuDev *dev, VuVirtq *vq)
vq->counter = vq->resubmit_list[0].counter + 1; vq->counter = vq->resubmit_list[0].counter + 1;
} }
/* in case of I/O hang after reconnecting */
if (eventfd_write(vq->kick_fd, 1)) {
return -1;
}
return 0; return 0;
} }
@@ -1436,6 +1431,20 @@ vu_set_vring_kick_exec(VuDev *dev, VhostUserMsg *vmsg)
vu_panic(dev, "Failed to check inflights for vq: %d\n", index); vu_panic(dev, "Failed to check inflights for vq: %d\n", index);
} }
/* Inject a kick to look for available vq buffers */
if (dev->vq[index].kick_fd != -1) {
int ret;
do {
ret = eventfd_write(dev->vq[index].kick_fd, 1);
} while (ret != 0 && errno == EINTR);
if (ret != 0 && errno != EAGAIN /* already readable */) {
vu_panic(dev, "Failed to inject kick during SET_VRING_KICK "
"on vq: %d with error: %m\n", index);
}
}
return false; return false;
} }