7f1c5b
From bffccbd59a2e2c641810cd7362c7b5ecf5989ed8 Mon Sep 17 00:00:00 2001
7f1c5b
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
7f1c5b
Date: Thu, 15 Dec 2022 12:31:35 +0100
7f1c5b
Subject: [PATCH 03/14] vhost: allocate SVQ device file descriptors at device
7f1c5b
 start
7f1c5b
MIME-Version: 1.0
7f1c5b
Content-Type: text/plain; charset=UTF-8
7f1c5b
Content-Transfer-Encoding: 8bit
7f1c5b
7f1c5b
RH-Author: Eugenio Pérez <eperezma@redhat.com>
7f1c5b
RH-MergeRequest: 136: vDPA ASID support in Qemu
7f1c5b
RH-Bugzilla: 2104412
7f1c5b
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
7f1c5b
RH-Acked-by: Cindy Lu <lulu@redhat.com>
7f1c5b
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
7f1c5b
RH-Commit: [3/13] bab2d43f0fc0d13a4917e706244b37e1a431b082 (eperezmartin/qemu-kvm)
7f1c5b
7f1c5b
The next patches will start control SVQ if possible. However, we don't
7f1c5b
know if that will be possible at qemu boot anymore.
7f1c5b
7f1c5b
Delay device file descriptors until we know it at device start. This
7f1c5b
will avoid to create them if the device does not support SVQ.
7f1c5b
7f1c5b
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
7f1c5b
Acked-by: Jason Wang <jasowang@redhat.com>
7f1c5b
Message-Id: <20221215113144.322011-4-eperezma@redhat.com>
7f1c5b
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
7f1c5b
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
7f1c5b
(cherry picked from commit 3cfb4d069cd2977b707fb519c455d7d416e1f4b0)
7f1c5b
---
7f1c5b
 hw/virtio/vhost-shadow-virtqueue.c | 31 ++------------------------
7f1c5b
 hw/virtio/vhost-vdpa.c             | 35 ++++++++++++++++++++++++------
7f1c5b
 2 files changed, 30 insertions(+), 36 deletions(-)
7f1c5b
7f1c5b
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
7f1c5b
index 264ddc166d..3b05bab44d 100644
7f1c5b
--- a/hw/virtio/vhost-shadow-virtqueue.c
7f1c5b
+++ b/hw/virtio/vhost-shadow-virtqueue.c
7f1c5b
@@ -715,43 +715,18 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq)
7f1c5b
  * @iova_tree: Tree to perform descriptors translations
7f1c5b
  * @ops: SVQ owner callbacks
7f1c5b
  * @ops_opaque: ops opaque pointer
7f1c5b
- *
7f1c5b
- * Returns the new virtqueue or NULL.
7f1c5b
- *
7f1c5b
- * In case of error, reason is reported through error_report.
7f1c5b
  */
7f1c5b
 VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree,
7f1c5b
                                     const VhostShadowVirtqueueOps *ops,
7f1c5b
                                     void *ops_opaque)
7f1c5b
 {
7f1c5b
-    g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
7f1c5b
-    int r;
7f1c5b
-
7f1c5b
-    r = event_notifier_init(&svq->hdev_kick, 0);
7f1c5b
-    if (r != 0) {
7f1c5b
-        error_report("Couldn't create kick event notifier: %s (%d)",
7f1c5b
-                     g_strerror(errno), errno);
7f1c5b
-        goto err_init_hdev_kick;
7f1c5b
-    }
7f1c5b
-
7f1c5b
-    r = event_notifier_init(&svq->hdev_call, 0);
7f1c5b
-    if (r != 0) {
7f1c5b
-        error_report("Couldn't create call event notifier: %s (%d)",
7f1c5b
-                     g_strerror(errno), errno);
7f1c5b
-        goto err_init_hdev_call;
7f1c5b
-    }
7f1c5b
+    VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
7f1c5b
 
7f1c5b
     event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND);
7f1c5b
     svq->iova_tree = iova_tree;
7f1c5b
     svq->ops = ops;
7f1c5b
     svq->ops_opaque = ops_opaque;
7f1c5b
-    return g_steal_pointer(&svq);
7f1c5b
-
7f1c5b
-err_init_hdev_call:
7f1c5b
-    event_notifier_cleanup(&svq->hdev_kick);
7f1c5b
-
7f1c5b
-err_init_hdev_kick:
7f1c5b
-    return NULL;
7f1c5b
+    return svq;
7f1c5b
 }
7f1c5b
 
7f1c5b
 /**
7f1c5b
@@ -763,7 +738,5 @@ void vhost_svq_free(gpointer pvq)
7f1c5b
 {
7f1c5b
     VhostShadowVirtqueue *vq = pvq;
7f1c5b
     vhost_svq_stop(vq);
7f1c5b
-    event_notifier_cleanup(&vq->hdev_kick);
7f1c5b
-    event_notifier_cleanup(&vq->hdev_call);
7f1c5b
     g_free(vq);
7f1c5b
 }
7f1c5b
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
7f1c5b
index 44e6a9b7b3..530d2ca362 100644
7f1c5b
--- a/hw/virtio/vhost-vdpa.c
7f1c5b
+++ b/hw/virtio/vhost-vdpa.c
7f1c5b
@@ -428,15 +428,11 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
7f1c5b
 
7f1c5b
     shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free);
7f1c5b
     for (unsigned n = 0; n < hdev->nvqs; ++n) {
7f1c5b
-        g_autoptr(VhostShadowVirtqueue) svq;
7f1c5b
+        VhostShadowVirtqueue *svq;
7f1c5b
 
7f1c5b
         svq = vhost_svq_new(v->iova_tree, v->shadow_vq_ops,
7f1c5b
                             v->shadow_vq_ops_opaque);
7f1c5b
-        if (unlikely(!svq)) {
7f1c5b
-            error_setg(errp, "Cannot create svq %u", n);
7f1c5b
-            return -1;
7f1c5b
-        }
7f1c5b
-        g_ptr_array_add(shadow_vqs, g_steal_pointer(&svq));
7f1c5b
+        g_ptr_array_add(shadow_vqs, svq);
7f1c5b
     }
7f1c5b
 
7f1c5b
     v->shadow_vqs = g_steal_pointer(&shadow_vqs);
7f1c5b
@@ -871,11 +867,23 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev,
7f1c5b
     const EventNotifier *event_notifier = &svq->hdev_kick;
7f1c5b
     int r;
7f1c5b
 
7f1c5b
+    r = event_notifier_init(&svq->hdev_kick, 0);
7f1c5b
+    if (r != 0) {
7f1c5b
+        error_setg_errno(errp, -r, "Couldn't create kick event notifier");
7f1c5b
+        goto err_init_hdev_kick;
7f1c5b
+    }
7f1c5b
+
7f1c5b
+    r = event_notifier_init(&svq->hdev_call, 0);
7f1c5b
+    if (r != 0) {
7f1c5b
+        error_setg_errno(errp, -r, "Couldn't create call event notifier");
7f1c5b
+        goto err_init_hdev_call;
7f1c5b
+    }
7f1c5b
+
7f1c5b
     file.fd = event_notifier_get_fd(event_notifier);
7f1c5b
     r = vhost_vdpa_set_vring_dev_kick(dev, &file;;
7f1c5b
     if (unlikely(r != 0)) {
7f1c5b
         error_setg_errno(errp, -r, "Can't set device kick fd");
7f1c5b
-        return r;
7f1c5b
+        goto err_init_set_dev_fd;
7f1c5b
     }
7f1c5b
 
7f1c5b
     event_notifier = &svq->hdev_call;
7f1c5b
@@ -883,8 +891,18 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev,
7f1c5b
     r = vhost_vdpa_set_vring_dev_call(dev, &file;;
7f1c5b
     if (unlikely(r != 0)) {
7f1c5b
         error_setg_errno(errp, -r, "Can't set device call fd");
7f1c5b
+        goto err_init_set_dev_fd;
7f1c5b
     }
7f1c5b
 
7f1c5b
+    return 0;
7f1c5b
+
7f1c5b
+err_init_set_dev_fd:
7f1c5b
+    event_notifier_set_handler(&svq->hdev_call, NULL);
7f1c5b
+
7f1c5b
+err_init_hdev_call:
7f1c5b
+    event_notifier_cleanup(&svq->hdev_kick);
7f1c5b
+
7f1c5b
+err_init_hdev_kick:
7f1c5b
     return r;
7f1c5b
 }
7f1c5b
 
7f1c5b
@@ -1096,6 +1114,9 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev)
7f1c5b
     for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {
7f1c5b
         VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
7f1c5b
         vhost_vdpa_svq_unmap_rings(dev, svq);
7f1c5b
+
7f1c5b
+        event_notifier_cleanup(&svq->hdev_kick);
7f1c5b
+        event_notifier_cleanup(&svq->hdev_call);
7f1c5b
     }
7f1c5b
 }
7f1c5b
 
7f1c5b
-- 
7f1c5b
2.31.1
7f1c5b