To split each SVQ in its own initialization routine let's us to restart a VQ individually, and to keep future vhost_vdpa_restart_queue symmetrical with vhost_vdpa_reset_queue.
Signed-off-by: Eugenio Pérez <epere...@redhat.com> --- hw/virtio/vhost-vdpa.c | 67 ++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c index df2515a247..7248072989 100644 --- a/hw/virtio/vhost-vdpa.c +++ b/hw/virtio/vhost-vdpa.c @@ -1223,6 +1223,46 @@ static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, return r == 0; } +static bool vhost_vdpa_svq_start(struct vhost_dev *dev, unsigned i, + Error **errp) +{ + struct vhost_vdpa *v = dev->opaque; + VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i); + VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); + struct vhost_vring_addr addr = { + .index = dev->vq_index + i, + }; + int r; + bool ok = vhost_vdpa_svq_setup(dev, svq, i, errp); + if (unlikely(!ok)) { + goto err; + } + + vhost_svq_start(svq, dev->vdev, vq, v->iova_tree); + ok = vhost_vdpa_svq_map_rings(dev, svq, &addr, errp); + if (unlikely(!ok)) { + goto err_map; + } + + /* Override vring GPA set by vhost subsystem */ + r = vhost_vdpa_set_vring_dev_addr(dev, &addr); + if (unlikely(r != 0)) { + error_setg_errno(errp, -r, "Cannot set device address"); + goto err_set_addr; + } + + return true; + +err_set_addr: + vhost_vdpa_svq_unmap_rings(dev, g_ptr_array_index(v->shadow_vqs, i)); + +err_map: + vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, i)); + +err: + return false; +} + static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) { struct vhost_vdpa *v = dev->opaque; @@ -1234,39 +1274,14 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) } for (i = 0; i < v->shadow_vqs->len; ++i) { - VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i); - VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); - struct vhost_vring_addr addr = { - .index = dev->vq_index + i, - }; - int r; - bool ok = vhost_vdpa_svq_setup(dev, svq, i, &err); + bool ok = vhost_vdpa_svq_start(dev, i, &err); if (unlikely(!ok)) { goto err; } - - vhost_svq_start(svq, dev->vdev, vq, v->iova_tree); - ok = vhost_vdpa_svq_map_rings(dev, svq, &addr, &err); - if (unlikely(!ok)) { - goto err_map; - } - - /* Override vring GPA set by vhost subsystem */ - r = vhost_vdpa_set_vring_dev_addr(dev, &addr); - if (unlikely(r != 0)) { - error_setg_errno(&err, -r, "Cannot set device address"); - goto err_set_addr; - } } return true; -err_set_addr: - vhost_vdpa_svq_unmap_rings(dev, g_ptr_array_index(v->shadow_vqs, i)); - -err_map: - vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, i)); - err: error_reportf_err(err, "Cannot setup SVQ %u: ", i); for (unsigned j = 0; j < i; ++j) { -- 2.39.3