[PATCH 1/2] vhost: support inflight save/load

Alexandr Moshkov posted 2 patches 3 weeks, 4 days ago
Maintainers: Raphael Norwitz <raphael@enfabrica.net>, "Michael S. Tsirkin" <mst@redhat.com>, Stefano Garzarella <sgarzare@redhat.com>, Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>, Eric Blake <eblake@redhat.com>, Markus Armbruster <armbru@redhat.com>
There is a newer version of this series
[PATCH 1/2] vhost: support inflight save/load
Posted by Alexandr Moshkov 3 weeks, 4 days ago
vhost_dev_load_inflight and vhost_dev_save_inflight have been deleted
by:

abe9ff2 ("vhost: Remove unused vhost_dev_{load|save}_inflight")

So, now they are needed for future commit.
Return them, and their helper vhost_dev_resize_inflight.

Signed-off-by: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
---
 hw/virtio/vhost.c         | 56 +++++++++++++++++++++++++++++++++++++++
 include/hw/virtio/vhost.h |  2 ++
 2 files changed, 58 insertions(+)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 266a11514a..16ce9a6037 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -2013,6 +2013,62 @@ int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
     return 0;
 }
 
+static int vhost_dev_resize_inflight(struct vhost_inflight *inflight,
+                                     uint64_t new_size)
+{
+    Error *err = NULL;
+    int fd = -1;
+    void *addr = qemu_memfd_alloc("vhost-inflight", new_size,
+                                  F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
+                                  &fd, &err);
+    if (err) {
+        error_report_err(err);
+        return -ENOMEM;
+    }
+
+    vhost_dev_free_inflight(inflight);
+    inflight->offset = 0;
+    inflight->addr = addr;
+    inflight->fd = fd;
+    inflight->size = new_size;
+
+    return 0;
+}
+
+void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f)
+{
+    if (inflight->addr) {
+        qemu_put_be64(f, inflight->size);
+        qemu_put_be16(f, inflight->queue_size);
+        qemu_put_buffer(f, inflight->addr, inflight->size);
+    } else {
+        qemu_put_be64(f, 0);
+    }
+}
+
+int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f)
+{
+    uint64_t size;
+
+    size = qemu_get_be64(f);
+    if (!size) {
+        return 0;
+    }
+
+    if (inflight->size != size) {
+        int ret = vhost_dev_resize_inflight(inflight, size);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    inflight->queue_size = qemu_get_be16(f);
+
+    qemu_get_buffer(f, inflight->addr, size);
+
+    return 0;
+}
+
 static int vhost_dev_set_vring_enable(struct vhost_dev *hdev, int enable)
 {
     if (!hdev->vhost_ops->vhost_set_vring_enable) {
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 08bbb4dfe9..da1f0c2361 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -402,6 +402,8 @@ int vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev,
 
 void vhost_dev_reset_inflight(struct vhost_inflight *inflight);
 void vhost_dev_free_inflight(struct vhost_inflight *inflight);
+void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f);
+int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f);
 int vhost_dev_prepare_inflight(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_set_inflight(struct vhost_dev *dev,
                            struct vhost_inflight *inflight);
-- 
2.34.1
Re: [PATCH 1/2] vhost: support inflight save/load
Posted by Peter Xu 3 weeks, 2 days ago
On Mon, Oct 20, 2025 at 10:44:14AM +0500, Alexandr Moshkov wrote:
> vhost_dev_load_inflight and vhost_dev_save_inflight have been deleted
> by:
> 
> abe9ff2 ("vhost: Remove unused vhost_dev_{load|save}_inflight")
> 
> So, now they are needed for future commit.
> Return them, and their helper vhost_dev_resize_inflight.
> 
> Signed-off-by: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
> ---
>  hw/virtio/vhost.c         | 56 +++++++++++++++++++++++++++++++++++++++
>  include/hw/virtio/vhost.h |  2 ++
>  2 files changed, 58 insertions(+)
> 
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 266a11514a..16ce9a6037 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -2013,6 +2013,62 @@ int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
>      return 0;
>  }
>  
> +static int vhost_dev_resize_inflight(struct vhost_inflight *inflight,
> +                                     uint64_t new_size)
> +{
> +    Error *err = NULL;
> +    int fd = -1;
> +    void *addr = qemu_memfd_alloc("vhost-inflight", new_size,
> +                                  F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
> +                                  &fd, &err);
> +    if (err) {
> +        error_report_err(err);
> +        return -ENOMEM;
> +    }
> +
> +    vhost_dev_free_inflight(inflight);
> +    inflight->offset = 0;
> +    inflight->addr = addr;
> +    inflight->fd = fd;
> +    inflight->size = new_size;
> +
> +    return 0;
> +}
> +
> +void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f)
> +{
> +    if (inflight->addr) {
> +        qemu_put_be64(f, inflight->size);
> +        qemu_put_be16(f, inflight->queue_size);
> +        qemu_put_buffer(f, inflight->addr, inflight->size);
> +    } else {
> +        qemu_put_be64(f, 0);
> +    }

Can we use VMSD (extra fields, or subsections) to describe any new data for
migration?

In general, we want to avoid using qemufile API as much as possible in the
future.  Hard-coded VMStateInfo is not suggested.

Thanks,

> +}
> +
> +int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f)
> +{
> +    uint64_t size;
> +
> +    size = qemu_get_be64(f);
> +    if (!size) {
> +        return 0;
> +    }
> +
> +    if (inflight->size != size) {
> +        int ret = vhost_dev_resize_inflight(inflight, size);
> +        if (ret < 0) {
> +            return ret;
> +        }
> +    }
> +
> +    inflight->queue_size = qemu_get_be16(f);
> +
> +    qemu_get_buffer(f, inflight->addr, size);
> +
> +    return 0;
> +}
> +
>  static int vhost_dev_set_vring_enable(struct vhost_dev *hdev, int enable)
>  {
>      if (!hdev->vhost_ops->vhost_set_vring_enable) {
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index 08bbb4dfe9..da1f0c2361 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -402,6 +402,8 @@ int vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev,
>  
>  void vhost_dev_reset_inflight(struct vhost_inflight *inflight);
>  void vhost_dev_free_inflight(struct vhost_inflight *inflight);
> +void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f);
> +int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f);
>  int vhost_dev_prepare_inflight(struct vhost_dev *hdev, VirtIODevice *vdev);
>  int vhost_dev_set_inflight(struct vhost_dev *dev,
>                             struct vhost_inflight *inflight);
> -- 
> 2.34.1
> 

-- 
Peter Xu
Re: [PATCH 1/2] vhost: support inflight save/load
Posted by Alexandr Moshkov 3 weeks, 1 day ago
Hi! Thanks for review!

On 10/22/25 00:29, Peter Xu wrote:
> On Mon, Oct 20, 2025 at 10:44:14AM +0500, Alexandr Moshkov wrote:
>> vhost_dev_load_inflight and vhost_dev_save_inflight have been deleted
>> by:
>>
>> abe9ff2 ("vhost: Remove unused vhost_dev_{load|save}_inflight")
>>
>> So, now they are needed for future commit.
>> Return them, and their helper vhost_dev_resize_inflight.
>>
>> Signed-off-by: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
>> ---
>>   hw/virtio/vhost.c         | 56 +++++++++++++++++++++++++++++++++++++++
>>   include/hw/virtio/vhost.h |  2 ++
>>   2 files changed, 58 insertions(+)
>>
>> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
>> index 266a11514a..16ce9a6037 100644
>> --- a/hw/virtio/vhost.c
>> +++ b/hw/virtio/vhost.c
>> @@ -2013,6 +2013,62 @@ int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
>>       return 0;
>>   }
>>   
>> +static int vhost_dev_resize_inflight(struct vhost_inflight *inflight,
>> +                                     uint64_t new_size)
>> +{
>> +    Error *err = NULL;
>> +    int fd = -1;
>> +    void *addr = qemu_memfd_alloc("vhost-inflight", new_size,
>> +                                  F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
>> +                                  &fd, &err);
>> +    if (err) {
>> +        error_report_err(err);
>> +        return -ENOMEM;
>> +    }
>> +
>> +    vhost_dev_free_inflight(inflight);
>> +    inflight->offset = 0;
>> +    inflight->addr = addr;
>> +    inflight->fd = fd;
>> +    inflight->size = new_size;
>> +
>> +    return 0;
>> +}
>> +
>> +void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f)
>> +{
>> +    if (inflight->addr) {
>> +        qemu_put_be64(f, inflight->size);
>> +        qemu_put_be16(f, inflight->queue_size);
>> +        qemu_put_buffer(f, inflight->addr, inflight->size);
>> +    } else {
>> +        qemu_put_be64(f, 0);
>> +    }
> Can we use VMSD (extra fields, or subsections) to describe any new data for
> migration?
>
> In general, we want to avoid using qemufile API as much as possible in the
> future.  Hard-coded VMStateInfo is not suggested.
>
> Thanks,
Ok! I'll fix it
>
>> +}
>> +
>> +int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f)
>> +{
>> +    uint64_t size;
>> +
>> +    size = qemu_get_be64(f);
>> +    if (!size) {
>> +        return 0;
>> +    }
>> +
>> +    if (inflight->size != size) {
>> +        int ret = vhost_dev_resize_inflight(inflight, size);
>> +        if (ret < 0) {
>> +            return ret;
>> +        }
>> +    }
>> +
>> +    inflight->queue_size = qemu_get_be16(f);
>> +
>> +    qemu_get_buffer(f, inflight->addr, size);
>> +
>> +    return 0;
>> +}
>> +
>>   static int vhost_dev_set_vring_enable(struct vhost_dev *hdev, int enable)
>>   {
>>       if (!hdev->vhost_ops->vhost_set_vring_enable) {
>> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
>> index 08bbb4dfe9..da1f0c2361 100644
>> --- a/include/hw/virtio/vhost.h
>> +++ b/include/hw/virtio/vhost.h
>> @@ -402,6 +402,8 @@ int vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev,
>>   
>>   void vhost_dev_reset_inflight(struct vhost_inflight *inflight);
>>   void vhost_dev_free_inflight(struct vhost_inflight *inflight);
>> +void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f);
>> +int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f);
>>   int vhost_dev_prepare_inflight(struct vhost_dev *hdev, VirtIODevice *vdev);
>>   int vhost_dev_set_inflight(struct vhost_dev *dev,
>>                              struct vhost_inflight *inflight);
>> -- 
>> 2.34.1
>>