[PATCH 11/16] vhost: introduce restart and release for vhost_dev's vqs

Kangjie Xu posted 16 patches 3 years, 6 months ago
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Jason Wang <jasowang@redhat.com>
[PATCH 11/16] vhost: introduce restart and release for vhost_dev's vqs
Posted by Kangjie Xu 3 years, 6 months ago
Introduce vhost_dev_virtqueue_restart(), which can restart the
virtqueue when the vhost has already started running.

Meanwhile, vhost_dev_virtqueue_release(), which can ummap the
vrings and the desc of a specific vq of a device.

Combining the two functions, we can reset a virtqueue with a
started vhost.

Signed-off-by: Kangjie Xu <kangjie.xu@linux.alibaba.com>
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
 hw/virtio/vhost.c         | 29 +++++++++++++++++++++++++++++
 include/hw/virtio/vhost.h |  6 ++++++
 2 files changed, 35 insertions(+)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index e467dfc7bc..d158d71866 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1904,3 +1904,32 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
 
     return -ENOSYS;
 }
+
+void vhost_dev_virtqueue_release(struct vhost_dev *hdev, VirtIODevice *vdev,
+                                 int vq_index)
+{
+    int idx = vq_index - hdev->vq_index;
+
+    idx = hdev->vhost_ops->vhost_get_vq_index(hdev, idx);
+
+    vhost_virtqueue_unmap(hdev,
+                          vdev,
+                          hdev->vqs + idx,
+                          hdev->vq_index + idx);
+}
+
+int vhost_dev_virtqueue_restart(struct vhost_dev *hdev, VirtIODevice *vdev,
+                                int vq_index)
+{
+    int idx = vq_index - hdev->vq_index;
+    int r = 0;
+
+    idx = hdev->vhost_ops->vhost_get_vq_index(hdev, idx);
+
+    r = vhost_virtqueue_start(hdev,
+                              vdev,
+                              hdev->vqs + idx,
+                              hdev->vq_index + idx);
+
+    return r;
+}
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index a346f23d13..7df7dbe24d 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -277,6 +277,12 @@ bool vhost_has_free_slot(void);
 int vhost_net_set_backend(struct vhost_dev *hdev,
                           struct vhost_vring_file *file);
 
+
+void vhost_dev_virtqueue_release(struct vhost_dev *hdev, VirtIODevice *vdev,
+                                 int vq_index);
+int vhost_dev_virtqueue_restart(struct vhost_dev *hdev, VirtIODevice *vdev,
+                                int vq_index);
+
 int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
 
 void vhost_dev_reset_inflight(struct vhost_inflight *inflight);
-- 
2.32.0
Re: [PATCH 11/16] vhost: introduce restart and release for vhost_dev's vqs
Posted by Jason Wang 3 years, 6 months ago
在 2022/7/18 19:17, Kangjie Xu 写道:
> Introduce vhost_dev_virtqueue_restart(), which can restart the
> virtqueue when the vhost has already started running.
>
> Meanwhile, vhost_dev_virtqueue_release(), which can ummap the
> vrings and the desc of a specific vq of a device.
>
> Combining the two functions, we can reset a virtqueue with a
> started vhost.
>
> Signed-off-by: Kangjie Xu <kangjie.xu@linux.alibaba.com>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> ---
>   hw/virtio/vhost.c         | 29 +++++++++++++++++++++++++++++
>   include/hw/virtio/vhost.h |  6 ++++++
>   2 files changed, 35 insertions(+)
>
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index e467dfc7bc..d158d71866 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -1904,3 +1904,32 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
>   
>       return -ENOSYS;
>   }
> +
> +void vhost_dev_virtqueue_release(struct vhost_dev *hdev, VirtIODevice *vdev,
> +                                 int vq_index)
> +{
> +    int idx = vq_index - hdev->vq_index;
> +
> +    idx = hdev->vhost_ops->vhost_get_vq_index(hdev, idx);
> +
> +    vhost_virtqueue_unmap(hdev,
> +                          vdev,
> +                          hdev->vqs + idx,
> +                          hdev->vq_index + idx);
> +}


Anything wrong that makes you can't use vhost_virtqueue_stop() here?

Thanks


> +
> +int vhost_dev_virtqueue_restart(struct vhost_dev *hdev, VirtIODevice *vdev,
> +                                int vq_index)
> +{
> +    int idx = vq_index - hdev->vq_index;
> +    int r = 0;
> +
> +    idx = hdev->vhost_ops->vhost_get_vq_index(hdev, idx);
> +
> +    r = vhost_virtqueue_start(hdev,
> +                              vdev,
> +                              hdev->vqs + idx,
> +                              hdev->vq_index + idx);
> +
> +    return r;
> +}
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index a346f23d13..7df7dbe24d 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -277,6 +277,12 @@ bool vhost_has_free_slot(void);
>   int vhost_net_set_backend(struct vhost_dev *hdev,
>                             struct vhost_vring_file *file);
>   
> +
> +void vhost_dev_virtqueue_release(struct vhost_dev *hdev, VirtIODevice *vdev,
> +                                 int vq_index);
> +int vhost_dev_virtqueue_restart(struct vhost_dev *hdev, VirtIODevice *vdev,
> +                                int vq_index);
> +
>   int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
>   
>   void vhost_dev_reset_inflight(struct vhost_inflight *inflight);


Re: [PATCH 11/16] vhost: introduce restart and release for vhost_dev's vqs
Posted by Kangjie Xu 3 years, 6 months ago
在 2022/7/26 12:13, Jason Wang 写道:
>
> 在 2022/7/18 19:17, Kangjie Xu 写道:
>> Introduce vhost_dev_virtqueue_restart(), which can restart the
>> virtqueue when the vhost has already started running.
>>
>> Meanwhile, vhost_dev_virtqueue_release(), which can ummap the
>> vrings and the desc of a specific vq of a device.
>>
>> Combining the two functions, we can reset a virtqueue with a
>> started vhost.
>>
>> Signed-off-by: Kangjie Xu <kangjie.xu@linux.alibaba.com>
>> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
>> ---
>>   hw/virtio/vhost.c         | 29 +++++++++++++++++++++++++++++
>>   include/hw/virtio/vhost.h |  6 ++++++
>>   2 files changed, 35 insertions(+)
>>
>> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
>> index e467dfc7bc..d158d71866 100644
>> --- a/hw/virtio/vhost.c
>> +++ b/hw/virtio/vhost.c
>> @@ -1904,3 +1904,32 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
>>         return -ENOSYS;
>>   }
>> +
>> +void vhost_dev_virtqueue_release(struct vhost_dev *hdev, 
>> VirtIODevice *vdev,
>> +                                 int vq_index)
>> +{
>> +    int idx = vq_index - hdev->vq_index;
>> +
>> +    idx = hdev->vhost_ops->vhost_get_vq_index(hdev, idx);
>> +
>> +    vhost_virtqueue_unmap(hdev,
>> +                          vdev,
>> +                          hdev->vqs + idx,
>> +                          hdev->vq_index + idx);
>> +}
>
>
> Anything wrong that makes you can't use vhost_virtqueue_stop() here?
>
> Thanks
>
>
Yeah, vhost_virtqueue_stop() will result in all the queues in the device 
being stopped.

In the scenario of DPDK-OVS, vhost_virtqueue_stop will send 
VHOST_USER_GET_VRING_BASE to DPDK. This message is meant to destroy the 
queue.

However, In DPDK, VHOST_USER_GET_VRING_BASE message will lead to 
vhost_destroy_device_notify(). This function will disable all the queues 
in the device.

Thus, when restarting the queue, other queues except the restarted one 
are still disabled.

On the other hand, I think it may be not necessary to destroy the queue. 
We can simply disable it. When restarting the queue, it will be 
intialized again.

I'm sorry I forgot to cc in the last email, so I resend this email.

Thanks
>> +
>> +int vhost_dev_virtqueue_restart(struct vhost_dev *hdev, VirtIODevice 
>> *vdev,
>> +                                int vq_index)
>> +{
>> +    int idx = vq_index - hdev->vq_index;
>> +    int r = 0;
>> +
>> +    idx = hdev->vhost_ops->vhost_get_vq_index(hdev, idx);
>> +
>> +    r = vhost_virtqueue_start(hdev,
>> +                              vdev,
>> +                              hdev->vqs + idx,
>> +                              hdev->vq_index + idx);
>> +
>> +    return r;
>> +}
>> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
>> index a346f23d13..7df7dbe24d 100644
>> --- a/include/hw/virtio/vhost.h
>> +++ b/include/hw/virtio/vhost.h
>> @@ -277,6 +277,12 @@ bool vhost_has_free_slot(void);
>>   int vhost_net_set_backend(struct vhost_dev *hdev,
>>                             struct vhost_vring_file *file);
>>   +
>> +void vhost_dev_virtqueue_release(struct vhost_dev *hdev, 
>> VirtIODevice *vdev,
>> +                                 int vq_index);
>> +int vhost_dev_virtqueue_restart(struct vhost_dev *hdev, VirtIODevice 
>> *vdev,
>> +                                int vq_index);
>> +
>>   int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, 
>> int write);
>>     void vhost_dev_reset_inflight(struct vhost_inflight *inflight);