On Fri, Nov 20, 2020 at 07:50:51PM +0100, Eugenio Pérez wrote: > -static inline bool vhost_vring_should_kick(VhostShadowVirtqueue *vq) > +static bool vhost_vring_should_kick_rcu(VhostShadowVirtqueue *vq) "vhost_vring_" is a confusing name. This is not related to vhost_virtqueue or the vhost_vring_* structs. vhost_shadow_vq_should_kick_rcu()? > { > - return virtio_queue_get_used_notify_split(vq->vq); > + VirtIODevice *vdev = vq->vdev; > + vq->num_added = 0; I'm surprised that a bool function modifies state. Is this assignment intentional? > +/* virtqueue_add: > + * @vq: The #VirtQueue > + * @elem: The #VirtQueueElement The copy-pasted doc comment doesn't match this function. > +int vhost_vring_add(VhostShadowVirtqueue *vq, VirtQueueElement *elem) > +{ > + int host_head = vhost_vring_add_split(vq, elem); > + if (vq->ring_id_maps[host_head]) { > + g_free(vq->ring_id_maps[host_head]); > + } VirtQueueElement is freed lazily? Is there a reason for this approach? I would have expected it to be freed when the used element is process by the kick fd handler. > diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c > index 9352c56bfa..304e0baa61 100644 > --- a/hw/virtio/vhost.c > +++ b/hw/virtio/vhost.c > @@ -956,8 +956,34 @@ static void handle_sw_lm_vq(VirtIODevice *vdev, VirtQueue *vq) > uint16_t idx = virtio_get_queue_index(vq); > > VhostShadowVirtqueue *svq = hdev->sw_lm_shadow_vq[idx]; > + VirtQueueElement *elem; > > - vhost_vring_kick(svq); > + /* > + * Make available all buffers as possible. > + */ > + do { > + if (virtio_queue_get_notification(vq)) { > + virtio_queue_set_notification(vq, false); > + } > + > + while (true) { > + int r; > + if (virtio_queue_full(vq)) { > + break; > + } Why is this check necessary? The guest cannot provide more descriptors than there is ring space. If that happens somehow then it's a driver error that is already reported in virtqueue_pop() below. I wonder if you added this because the vring implementation above doesn't support indirect descriptors? It's easy to exhaust the vhost hdev vring while there is still room in the VirtIODevice's VirtQueue vring.