Message ID | 20241218143453.1573185-1-lvivier@redhat.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | virtio-net: vhost-user: Implement internal migration | expand |
I tested this patch with virtio-net regression tests,everything works fine. Tested-by: Lei Yang <leiyang@redhat.com> On Wed, Dec 18, 2024 at 10:36 PM Laurent Vivier <lvivier@redhat.com> wrote: > > Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net > with vhost-user backend. > > Cc: Hanna Czenczek <hreitz@redhat.com> > Signed-off-by: Laurent Vivier <lvivier@redhat.com> > --- > hw/net/virtio-net.c | 135 ++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 112 insertions(+), 23 deletions(-) > > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c > index 6e8c51a2dbce..b4d9e96dc0d7 100644 > --- a/hw/net/virtio-net.c > +++ b/hw/net/virtio-net.c > @@ -3337,6 +3337,117 @@ static const VMStateDescription vmstate_virtio_net_rss = { > }, > }; > > +static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) > +{ > + VirtIONet *n = VIRTIO_NET(vdev); > + NetClientState *nc; > + struct vhost_net *net; > + > + if (!n->nic) { > + return NULL; > + } > + > + nc = qemu_get_queue(n->nic); > + if (!nc) { > + return NULL; > + } > + > + net = get_vhost_net(nc->peer); > + if (!net) { > + return NULL; > + } > + > + return &net->dev; > +} > + > +static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size, > + const VMStateField *field, > + JSONWriter *vmdesc) > +{ > + VirtIONet *n = pv; > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > + struct vhost_dev *vhdev; > + Error *local_error = NULL; > + int ret; > + > + vhdev = virtio_net_get_vhost(vdev); > + if (vhdev == NULL) { > + error_reportf_err(local_error, > + "Error getting vhost back-end of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return -1; > + } > + > + ret = vhost_save_backend_state(vhdev, f, &local_error); > + if (ret < 0) { > + error_reportf_err(local_error, > + "Error saving back-end state of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return ret; > + } > + > + return 0; > +} > + > +static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size, > + const VMStateField *field) > +{ > + VirtIONet *n = pv; > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > + struct vhost_dev *vhdev; > + Error *local_error = NULL; > + int ret; > + > + vhdev = virtio_net_get_vhost(vdev); > + if (vhdev == NULL) { > + error_reportf_err(local_error, > + "Error getting vhost back-end of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return -1; > + } > + > + ret = vhost_load_backend_state(vhdev, f, &local_error); > + if (ret < 0) { > + error_reportf_err(local_error, > + "Error loading back-end state of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return ret; > + } > + > + return 0; > +} > + > +static bool vhost_user_net_is_internal_migration(void *opaque) > +{ > + VirtIONet *n = opaque; > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > + struct vhost_dev *vhdev; > + > + vhdev = virtio_net_get_vhost(vdev); > + if (vhdev == NULL) { > + return false; > + } > + > + return vhost_supports_device_state(vhdev); > +} > + > +static const VMStateDescription vhost_user_net_backend_state = { > + .name = "virtio-net-device/backend", > + .version_id = 0, > + .needed = vhost_user_net_is_internal_migration, > + .fields = (const VMStateField[]) { > + { > + .name = "backend", > + .info = &(const VMStateInfo) { > + .name = "virtio-net vhost-user backend state", > + .get = vhost_user_net_load_state, > + .put = vhost_user_net_save_state, > + }, > + }, > + VMSTATE_END_OF_LIST() > + } > +}; > + > static const VMStateDescription vmstate_virtio_net_device = { > .name = "virtio-net-device", > .version_id = VIRTIO_NET_VM_VERSION, > @@ -3389,6 +3500,7 @@ static const VMStateDescription vmstate_virtio_net_device = { > }, > .subsections = (const VMStateDescription * const []) { > &vmstate_virtio_net_rss, > + &vhost_user_net_backend_state, > NULL > } > }; > @@ -3950,29 +4062,6 @@ static bool dev_unplug_pending(void *opaque) > return vdc->primary_unplug_pending(dev); > } > > -static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) > -{ > - VirtIONet *n = VIRTIO_NET(vdev); > - NetClientState *nc; > - struct vhost_net *net; > - > - if (!n->nic) { > - return NULL; > - } > - > - nc = qemu_get_queue(n->nic); > - if (!nc) { > - return NULL; > - } > - > - net = get_vhost_net(nc->peer); > - if (!net) { > - return NULL; > - } > - > - return &net->dev; > -} > - > static const VMStateDescription vmstate_virtio_net = { > .name = "virtio-net", > .minimum_version_id = VIRTIO_NET_VM_VERSION, > -- > 2.47.1 > >
On 18/12/2024 15:34, Laurent Vivier wrote: > Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net > with vhost-user backend. > > Cc: Hanna Czenczek <hreitz@redhat.com> > Signed-off-by: Laurent Vivier <lvivier@redhat.com> > --- > hw/net/virtio-net.c | 135 ++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 112 insertions(+), 23 deletions(-) > > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c > index 6e8c51a2dbce..b4d9e96dc0d7 100644 > --- a/hw/net/virtio-net.c > +++ b/hw/net/virtio-net.c > @@ -3337,6 +3337,117 @@ static const VMStateDescription vmstate_virtio_net_rss = { > }, > }; > > +static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) > +{ > + VirtIONet *n = VIRTIO_NET(vdev); > + NetClientState *nc; > + struct vhost_net *net; > + > + if (!n->nic) { > + return NULL; > + } > + > + nc = qemu_get_queue(n->nic); > + if (!nc) { > + return NULL; > + } > + > + net = get_vhost_net(nc->peer); > + if (!net) { > + return NULL; > + } > + > + return &net->dev; > +} > + > +static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size, > + const VMStateField *field, > + JSONWriter *vmdesc) > +{ > + VirtIONet *n = pv; > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > + struct vhost_dev *vhdev; > + Error *local_error = NULL; > + int ret; > + > + vhdev = virtio_net_get_vhost(vdev); > + if (vhdev == NULL) { > + error_reportf_err(local_error, > + "Error getting vhost back-end of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return -1; > + } > + > + ret = vhost_save_backend_state(vhdev, f, &local_error); > + if (ret < 0) { > + error_reportf_err(local_error, > + "Error saving back-end state of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return ret; > + } > + > + return 0; > +} > + > +static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size, > + const VMStateField *field) > +{ > + VirtIONet *n = pv; > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > + struct vhost_dev *vhdev; > + Error *local_error = NULL; > + int ret; > + > + vhdev = virtio_net_get_vhost(vdev); > + if (vhdev == NULL) { > + error_reportf_err(local_error, > + "Error getting vhost back-end of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return -1; > + } > + > + ret = vhost_load_backend_state(vhdev, f, &local_error); > + if (ret < 0) { > + error_reportf_err(local_error, > + "Error loading back-end state of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return ret; > + } > + > + return 0; > +} > + > +static bool vhost_user_net_is_internal_migration(void *opaque) > +{ > + VirtIONet *n = opaque; > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > + struct vhost_dev *vhdev; > + > + vhdev = virtio_net_get_vhost(vdev); > + if (vhdev == NULL) { > + return false; > + } > + > + return vhost_supports_device_state(vhdev); > +} > + > +static const VMStateDescription vhost_user_net_backend_state = { > + .name = "virtio-net-device/backend", > + .version_id = 0, > + .needed = vhost_user_net_is_internal_migration, > + .fields = (const VMStateField[]) { > + { > + .name = "backend", > + .info = &(const VMStateInfo) { > + .name = "virtio-net vhost-user backend state", > + .get = vhost_user_net_load_state, > + .put = vhost_user_net_save_state, > + }, > + }, > + VMSTATE_END_OF_LIST() > + } > +}; > + > static const VMStateDescription vmstate_virtio_net_device = { > .name = "virtio-net-device", > .version_id = VIRTIO_NET_VM_VERSION, > @@ -3389,6 +3500,7 @@ static const VMStateDescription vmstate_virtio_net_device = { > }, > .subsections = (const VMStateDescription * const []) { > &vmstate_virtio_net_rss, > + &vhost_user_net_backend_state, > NULL > } > }; > @@ -3950,29 +4062,6 @@ static bool dev_unplug_pending(void *opaque) > return vdc->primary_unplug_pending(dev); > } > > -static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) > -{ > - VirtIONet *n = VIRTIO_NET(vdev); > - NetClientState *nc; > - struct vhost_net *net; > - > - if (!n->nic) { > - return NULL; > - } > - > - nc = qemu_get_queue(n->nic); > - if (!nc) { > - return NULL; > - } > - > - net = get_vhost_net(nc->peer); > - if (!net) { > - return NULL; > - } > - > - return &net->dev; > -} > - > static const VMStateDescription vmstate_virtio_net = { > .name = "virtio-net", > .minimum_version_id = VIRTIO_NET_VM_VERSION, Any comment on this patch? This is roughly what we already have for vhost-user-fs in bca3e2a13814 ("vhost-user-fs: Implement internal migration") Thanks, Laurent
On Wed, Dec 18, 2024 at 03:34:53PM +0100, Laurent Vivier wrote: > Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net > with vhost-user backend. > > Cc: Hanna Czenczek <hreitz@redhat.com> > Signed-off-by: Laurent Vivier <lvivier@redhat.com> Breaks windows builds: https://gitlab.com/mstredhat/qemu/-/jobs/8855973625 > --- > hw/net/virtio-net.c | 135 ++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 112 insertions(+), 23 deletions(-) > > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c > index 6e8c51a2dbce..b4d9e96dc0d7 100644 > --- a/hw/net/virtio-net.c > +++ b/hw/net/virtio-net.c > @@ -3337,6 +3337,117 @@ static const VMStateDescription vmstate_virtio_net_rss = { > }, > }; > > +static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) > +{ > + VirtIONet *n = VIRTIO_NET(vdev); > + NetClientState *nc; > + struct vhost_net *net; > + > + if (!n->nic) { > + return NULL; > + } > + > + nc = qemu_get_queue(n->nic); > + if (!nc) { > + return NULL; > + } > + > + net = get_vhost_net(nc->peer); > + if (!net) { > + return NULL; > + } > + > + return &net->dev; > +} > + > +static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size, > + const VMStateField *field, > + JSONWriter *vmdesc) > +{ > + VirtIONet *n = pv; > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > + struct vhost_dev *vhdev; > + Error *local_error = NULL; > + int ret; > + > + vhdev = virtio_net_get_vhost(vdev); > + if (vhdev == NULL) { > + error_reportf_err(local_error, > + "Error getting vhost back-end of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return -1; > + } > + > + ret = vhost_save_backend_state(vhdev, f, &local_error); > + if (ret < 0) { > + error_reportf_err(local_error, > + "Error saving back-end state of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return ret; > + } > + > + return 0; > +} > + > +static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size, > + const VMStateField *field) > +{ > + VirtIONet *n = pv; > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > + struct vhost_dev *vhdev; > + Error *local_error = NULL; > + int ret; > + > + vhdev = virtio_net_get_vhost(vdev); > + if (vhdev == NULL) { > + error_reportf_err(local_error, > + "Error getting vhost back-end of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return -1; > + } > + > + ret = vhost_load_backend_state(vhdev, f, &local_error); > + if (ret < 0) { > + error_reportf_err(local_error, > + "Error loading back-end state of %s device %s: ", > + vdev->name, vdev->parent_obj.canonical_path); > + return ret; > + } > + > + return 0; > +} > + > +static bool vhost_user_net_is_internal_migration(void *opaque) > +{ > + VirtIONet *n = opaque; > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > + struct vhost_dev *vhdev; > + > + vhdev = virtio_net_get_vhost(vdev); > + if (vhdev == NULL) { > + return false; > + } > + > + return vhost_supports_device_state(vhdev); > +} > + > +static const VMStateDescription vhost_user_net_backend_state = { > + .name = "virtio-net-device/backend", > + .version_id = 0, > + .needed = vhost_user_net_is_internal_migration, > + .fields = (const VMStateField[]) { > + { > + .name = "backend", > + .info = &(const VMStateInfo) { > + .name = "virtio-net vhost-user backend state", > + .get = vhost_user_net_load_state, > + .put = vhost_user_net_save_state, > + }, > + }, > + VMSTATE_END_OF_LIST() > + } > +}; > + > static const VMStateDescription vmstate_virtio_net_device = { > .name = "virtio-net-device", > .version_id = VIRTIO_NET_VM_VERSION, > @@ -3389,6 +3500,7 @@ static const VMStateDescription vmstate_virtio_net_device = { > }, > .subsections = (const VMStateDescription * const []) { > &vmstate_virtio_net_rss, > + &vhost_user_net_backend_state, > NULL > } > }; > @@ -3950,29 +4062,6 @@ static bool dev_unplug_pending(void *opaque) > return vdc->primary_unplug_pending(dev); > } > > -static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) > -{ > - VirtIONet *n = VIRTIO_NET(vdev); > - NetClientState *nc; > - struct vhost_net *net; > - > - if (!n->nic) { > - return NULL; > - } > - > - nc = qemu_get_queue(n->nic); > - if (!nc) { > - return NULL; > - } > - > - net = get_vhost_net(nc->peer); > - if (!net) { > - return NULL; > - } > - > - return &net->dev; > -} > - > static const VMStateDescription vmstate_virtio_net = { > .name = "virtio-net", > .minimum_version_id = VIRTIO_NET_VM_VERSION, > -- > 2.47.1
On 15/01/2025 11:10, Michael S. Tsirkin wrote: > On Wed, Dec 18, 2024 at 03:34:53PM +0100, Laurent Vivier wrote: >> Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net >> with vhost-user backend. >> >> Cc: Hanna Czenczek <hreitz@redhat.com> >> Signed-off-by: Laurent Vivier <lvivier@redhat.com> > > > Breaks windows builds: > > https://gitlab.com/mstredhat/qemu/-/jobs/8855973625 Thank you Michael. I fix that, test and send new version soon. Laurent > >> --- >> hw/net/virtio-net.c | 135 ++++++++++++++++++++++++++++++++++++-------- >> 1 file changed, 112 insertions(+), 23 deletions(-) >> >> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c >> index 6e8c51a2dbce..b4d9e96dc0d7 100644 >> --- a/hw/net/virtio-net.c >> +++ b/hw/net/virtio-net.c >> @@ -3337,6 +3337,117 @@ static const VMStateDescription vmstate_virtio_net_rss = { >> }, >> }; >> >> +static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) >> +{ >> + VirtIONet *n = VIRTIO_NET(vdev); >> + NetClientState *nc; >> + struct vhost_net *net; >> + >> + if (!n->nic) { >> + return NULL; >> + } >> + >> + nc = qemu_get_queue(n->nic); >> + if (!nc) { >> + return NULL; >> + } >> + >> + net = get_vhost_net(nc->peer); >> + if (!net) { >> + return NULL; >> + } >> + >> + return &net->dev; >> +} >> + >> +static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size, >> + const VMStateField *field, >> + JSONWriter *vmdesc) >> +{ >> + VirtIONet *n = pv; >> + VirtIODevice *vdev = VIRTIO_DEVICE(n); >> + struct vhost_dev *vhdev; >> + Error *local_error = NULL; >> + int ret; >> + >> + vhdev = virtio_net_get_vhost(vdev); >> + if (vhdev == NULL) { >> + error_reportf_err(local_error, >> + "Error getting vhost back-end of %s device %s: ", >> + vdev->name, vdev->parent_obj.canonical_path); >> + return -1; >> + } >> + >> + ret = vhost_save_backend_state(vhdev, f, &local_error); >> + if (ret < 0) { >> + error_reportf_err(local_error, >> + "Error saving back-end state of %s device %s: ", >> + vdev->name, vdev->parent_obj.canonical_path); >> + return ret; >> + } >> + >> + return 0; >> +} >> + >> +static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size, >> + const VMStateField *field) >> +{ >> + VirtIONet *n = pv; >> + VirtIODevice *vdev = VIRTIO_DEVICE(n); >> + struct vhost_dev *vhdev; >> + Error *local_error = NULL; >> + int ret; >> + >> + vhdev = virtio_net_get_vhost(vdev); >> + if (vhdev == NULL) { >> + error_reportf_err(local_error, >> + "Error getting vhost back-end of %s device %s: ", >> + vdev->name, vdev->parent_obj.canonical_path); >> + return -1; >> + } >> + >> + ret = vhost_load_backend_state(vhdev, f, &local_error); >> + if (ret < 0) { >> + error_reportf_err(local_error, >> + "Error loading back-end state of %s device %s: ", >> + vdev->name, vdev->parent_obj.canonical_path); >> + return ret; >> + } >> + >> + return 0; >> +} >> + >> +static bool vhost_user_net_is_internal_migration(void *opaque) >> +{ >> + VirtIONet *n = opaque; >> + VirtIODevice *vdev = VIRTIO_DEVICE(n); >> + struct vhost_dev *vhdev; >> + >> + vhdev = virtio_net_get_vhost(vdev); >> + if (vhdev == NULL) { >> + return false; >> + } >> + >> + return vhost_supports_device_state(vhdev); >> +} >> + >> +static const VMStateDescription vhost_user_net_backend_state = { >> + .name = "virtio-net-device/backend", >> + .version_id = 0, >> + .needed = vhost_user_net_is_internal_migration, >> + .fields = (const VMStateField[]) { >> + { >> + .name = "backend", >> + .info = &(const VMStateInfo) { >> + .name = "virtio-net vhost-user backend state", >> + .get = vhost_user_net_load_state, >> + .put = vhost_user_net_save_state, >> + }, >> + }, >> + VMSTATE_END_OF_LIST() >> + } >> +}; >> + >> static const VMStateDescription vmstate_virtio_net_device = { >> .name = "virtio-net-device", >> .version_id = VIRTIO_NET_VM_VERSION, >> @@ -3389,6 +3500,7 @@ static const VMStateDescription vmstate_virtio_net_device = { >> }, >> .subsections = (const VMStateDescription * const []) { >> &vmstate_virtio_net_rss, >> + &vhost_user_net_backend_state, >> NULL >> } >> }; >> @@ -3950,29 +4062,6 @@ static bool dev_unplug_pending(void *opaque) >> return vdc->primary_unplug_pending(dev); >> } >> >> -static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) >> -{ >> - VirtIONet *n = VIRTIO_NET(vdev); >> - NetClientState *nc; >> - struct vhost_net *net; >> - >> - if (!n->nic) { >> - return NULL; >> - } >> - >> - nc = qemu_get_queue(n->nic); >> - if (!nc) { >> - return NULL; >> - } >> - >> - net = get_vhost_net(nc->peer); >> - if (!net) { >> - return NULL; >> - } >> - >> - return &net->dev; >> -} >> - >> static const VMStateDescription vmstate_virtio_net = { >> .name = "virtio-net", >> .minimum_version_id = VIRTIO_NET_VM_VERSION, >> -- >> 2.47.1 >
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 6e8c51a2dbce..b4d9e96dc0d7 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -3337,6 +3337,117 @@ static const VMStateDescription vmstate_virtio_net_rss = { }, }; +static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) +{ + VirtIONet *n = VIRTIO_NET(vdev); + NetClientState *nc; + struct vhost_net *net; + + if (!n->nic) { + return NULL; + } + + nc = qemu_get_queue(n->nic); + if (!nc) { + return NULL; + } + + net = get_vhost_net(nc->peer); + if (!net) { + return NULL; + } + + return &net->dev; +} + +static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size, + const VMStateField *field, + JSONWriter *vmdesc) +{ + VirtIONet *n = pv; + VirtIODevice *vdev = VIRTIO_DEVICE(n); + struct vhost_dev *vhdev; + Error *local_error = NULL; + int ret; + + vhdev = virtio_net_get_vhost(vdev); + if (vhdev == NULL) { + error_reportf_err(local_error, + "Error getting vhost back-end of %s device %s: ", + vdev->name, vdev->parent_obj.canonical_path); + return -1; + } + + ret = vhost_save_backend_state(vhdev, f, &local_error); + if (ret < 0) { + error_reportf_err(local_error, + "Error saving back-end state of %s device %s: ", + vdev->name, vdev->parent_obj.canonical_path); + return ret; + } + + return 0; +} + +static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size, + const VMStateField *field) +{ + VirtIONet *n = pv; + VirtIODevice *vdev = VIRTIO_DEVICE(n); + struct vhost_dev *vhdev; + Error *local_error = NULL; + int ret; + + vhdev = virtio_net_get_vhost(vdev); + if (vhdev == NULL) { + error_reportf_err(local_error, + "Error getting vhost back-end of %s device %s: ", + vdev->name, vdev->parent_obj.canonical_path); + return -1; + } + + ret = vhost_load_backend_state(vhdev, f, &local_error); + if (ret < 0) { + error_reportf_err(local_error, + "Error loading back-end state of %s device %s: ", + vdev->name, vdev->parent_obj.canonical_path); + return ret; + } + + return 0; +} + +static bool vhost_user_net_is_internal_migration(void *opaque) +{ + VirtIONet *n = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(n); + struct vhost_dev *vhdev; + + vhdev = virtio_net_get_vhost(vdev); + if (vhdev == NULL) { + return false; + } + + return vhost_supports_device_state(vhdev); +} + +static const VMStateDescription vhost_user_net_backend_state = { + .name = "virtio-net-device/backend", + .version_id = 0, + .needed = vhost_user_net_is_internal_migration, + .fields = (const VMStateField[]) { + { + .name = "backend", + .info = &(const VMStateInfo) { + .name = "virtio-net vhost-user backend state", + .get = vhost_user_net_load_state, + .put = vhost_user_net_save_state, + }, + }, + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_virtio_net_device = { .name = "virtio-net-device", .version_id = VIRTIO_NET_VM_VERSION, @@ -3389,6 +3500,7 @@ static const VMStateDescription vmstate_virtio_net_device = { }, .subsections = (const VMStateDescription * const []) { &vmstate_virtio_net_rss, + &vhost_user_net_backend_state, NULL } }; @@ -3950,29 +4062,6 @@ static bool dev_unplug_pending(void *opaque) return vdc->primary_unplug_pending(dev); } -static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) -{ - VirtIONet *n = VIRTIO_NET(vdev); - NetClientState *nc; - struct vhost_net *net; - - if (!n->nic) { - return NULL; - } - - nc = qemu_get_queue(n->nic); - if (!nc) { - return NULL; - } - - net = get_vhost_net(nc->peer); - if (!net) { - return NULL; - } - - return &net->dev; -} - static const VMStateDescription vmstate_virtio_net = { .name = "virtio-net", .minimum_version_id = VIRTIO_NET_VM_VERSION,
Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net with vhost-user backend. Cc: Hanna Czenczek <hreitz@redhat.com> Signed-off-by: Laurent Vivier <lvivier@redhat.com> --- hw/net/virtio-net.c | 135 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 112 insertions(+), 23 deletions(-)