vdpa_sim: Implement resume vdpa op
authorSebastien Boeuf <sebastien.boeuf@intel.com>
Tue, 3 Jan 2023 10:51:08 +0000 (11:51 +0100)
committerMichael S. Tsirkin <mst@redhat.com>
Tue, 21 Feb 2023 00:26:56 +0000 (19:26 -0500)
Implement resume operation for vdpa_sim devices, so vhost-vdpa will
offer that backend feature and userspace can effectively resume the
device.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Message-Id: <15a4566826033c5dd9a2167e5cfb0ef4d90cea49.1672742878.git.sebastien.boeuf@intel.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
drivers/vdpa/vdpa_sim/vdpa_sim.c
drivers/vdpa/vdpa_sim/vdpa_sim.h

index 8839232a3fcbc0e30404bba70e1da3055cb0d5aa..fb9000131ac03e3ac1b791461c0bbcc93ec9c606 100644 (file)
@@ -358,6 +358,12 @@ static void vdpasim_kick_vq(struct vdpa_device *vdpa, u16 idx)
        struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
        struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
 
+       if (!vdpasim->running &&
+           (vdpasim->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+               vdpasim->pending_kick = true;
+               return;
+       }
+
        if (vq->ready)
                schedule_work(&vdpasim->work);
 }
@@ -528,6 +534,27 @@ static int vdpasim_suspend(struct vdpa_device *vdpa)
        return 0;
 }
 
+static int vdpasim_resume(struct vdpa_device *vdpa)
+{
+       struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
+       int i;
+
+       spin_lock(&vdpasim->lock);
+       vdpasim->running = true;
+
+       if (vdpasim->pending_kick) {
+               /* Process pending descriptors */
+               for (i = 0; i < vdpasim->dev_attr.nvqs; ++i)
+                       vdpasim_kick_vq(vdpa, i);
+
+               vdpasim->pending_kick = false;
+       }
+
+       spin_unlock(&vdpasim->lock);
+
+       return 0;
+}
+
 static size_t vdpasim_get_config_size(struct vdpa_device *vdpa)
 {
        struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
@@ -720,6 +747,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = {
        .set_status             = vdpasim_set_status,
        .reset                  = vdpasim_reset,
        .suspend                = vdpasim_suspend,
+       .resume                 = vdpasim_resume,
        .get_config_size        = vdpasim_get_config_size,
        .get_config             = vdpasim_get_config,
        .set_config             = vdpasim_set_config,
@@ -753,6 +781,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = {
        .set_status             = vdpasim_set_status,
        .reset                  = vdpasim_reset,
        .suspend                = vdpasim_suspend,
+       .resume                 = vdpasim_resume,
        .get_config_size        = vdpasim_get_config_size,
        .get_config             = vdpasim_get_config,
        .set_config             = vdpasim_set_config,
index 0e78737dcc166effb6f7f8e8b3b141e7a2cc9155..a745605589e20c6af5199321492939a6235fa897 100644 (file)
@@ -67,6 +67,7 @@ struct vdpasim {
        u64 features;
        u32 groups;
        bool running;
+       bool pending_kick;
        /* spinlock to synchronize iommu table */
        spinlock_t iommu_lock;
 };