Skip to content

Commit 60f543a

Browse files
viviermstsirkin
authored andcommitted
virtio-net: vhost-user: Implement internal migration
Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net with vhost-user backend. Cc: Hanna Czenczek <[email protected]> Signed-off-by: Laurent Vivier <[email protected]> Message-Id: <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent 3f65357 commit 60f543a

File tree

1 file changed

+112
-23
lines changed

1 file changed

+112
-23
lines changed

hw/net/virtio-net.c

Lines changed: 112 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3337,6 +3337,117 @@ static const VMStateDescription vmstate_virtio_net_rss = {
33373337
},
33383338
};
33393339

3340+
static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev)
3341+
{
3342+
VirtIONet *n = VIRTIO_NET(vdev);
3343+
NetClientState *nc;
3344+
struct vhost_net *net;
3345+
3346+
if (!n->nic) {
3347+
return NULL;
3348+
}
3349+
3350+
nc = qemu_get_queue(n->nic);
3351+
if (!nc) {
3352+
return NULL;
3353+
}
3354+
3355+
net = get_vhost_net(nc->peer);
3356+
if (!net) {
3357+
return NULL;
3358+
}
3359+
3360+
return &net->dev;
3361+
}
3362+
3363+
static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size,
3364+
const VMStateField *field,
3365+
JSONWriter *vmdesc)
3366+
{
3367+
VirtIONet *n = pv;
3368+
VirtIODevice *vdev = VIRTIO_DEVICE(n);
3369+
struct vhost_dev *vhdev;
3370+
Error *local_error = NULL;
3371+
int ret;
3372+
3373+
vhdev = virtio_net_get_vhost(vdev);
3374+
if (vhdev == NULL) {
3375+
error_reportf_err(local_error,
3376+
"Error getting vhost back-end of %s device %s: ",
3377+
vdev->name, vdev->parent_obj.canonical_path);
3378+
return -1;
3379+
}
3380+
3381+
ret = vhost_save_backend_state(vhdev, f, &local_error);
3382+
if (ret < 0) {
3383+
error_reportf_err(local_error,
3384+
"Error saving back-end state of %s device %s: ",
3385+
vdev->name, vdev->parent_obj.canonical_path);
3386+
return ret;
3387+
}
3388+
3389+
return 0;
3390+
}
3391+
3392+
static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size,
3393+
const VMStateField *field)
3394+
{
3395+
VirtIONet *n = pv;
3396+
VirtIODevice *vdev = VIRTIO_DEVICE(n);
3397+
struct vhost_dev *vhdev;
3398+
Error *local_error = NULL;
3399+
int ret;
3400+
3401+
vhdev = virtio_net_get_vhost(vdev);
3402+
if (vhdev == NULL) {
3403+
error_reportf_err(local_error,
3404+
"Error getting vhost back-end of %s device %s: ",
3405+
vdev->name, vdev->parent_obj.canonical_path);
3406+
return -1;
3407+
}
3408+
3409+
ret = vhost_load_backend_state(vhdev, f, &local_error);
3410+
if (ret < 0) {
3411+
error_reportf_err(local_error,
3412+
"Error loading back-end state of %s device %s: ",
3413+
vdev->name, vdev->parent_obj.canonical_path);
3414+
return ret;
3415+
}
3416+
3417+
return 0;
3418+
}
3419+
3420+
static bool vhost_user_net_is_internal_migration(void *opaque)
3421+
{
3422+
VirtIONet *n = opaque;
3423+
VirtIODevice *vdev = VIRTIO_DEVICE(n);
3424+
struct vhost_dev *vhdev;
3425+
3426+
vhdev = virtio_net_get_vhost(vdev);
3427+
if (vhdev == NULL) {
3428+
return false;
3429+
}
3430+
3431+
return vhost_supports_device_state(vhdev);
3432+
}
3433+
3434+
static const VMStateDescription vhost_user_net_backend_state = {
3435+
.name = "virtio-net-device/backend",
3436+
.version_id = 0,
3437+
.needed = vhost_user_net_is_internal_migration,
3438+
.fields = (const VMStateField[]) {
3439+
{
3440+
.name = "backend",
3441+
.info = &(const VMStateInfo) {
3442+
.name = "virtio-net vhost-user backend state",
3443+
.get = vhost_user_net_load_state,
3444+
.put = vhost_user_net_save_state,
3445+
},
3446+
},
3447+
VMSTATE_END_OF_LIST()
3448+
}
3449+
};
3450+
33403451
static const VMStateDescription vmstate_virtio_net_device = {
33413452
.name = "virtio-net-device",
33423453
.version_id = VIRTIO_NET_VM_VERSION,
@@ -3389,6 +3500,7 @@ static const VMStateDescription vmstate_virtio_net_device = {
33893500
},
33903501
.subsections = (const VMStateDescription * const []) {
33913502
&vmstate_virtio_net_rss,
3503+
&vhost_user_net_backend_state,
33923504
NULL
33933505
}
33943506
};
@@ -3950,29 +4062,6 @@ static bool dev_unplug_pending(void *opaque)
39504062
return vdc->primary_unplug_pending(dev);
39514063
}
39524064

3953-
static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev)
3954-
{
3955-
VirtIONet *n = VIRTIO_NET(vdev);
3956-
NetClientState *nc;
3957-
struct vhost_net *net;
3958-
3959-
if (!n->nic) {
3960-
return NULL;
3961-
}
3962-
3963-
nc = qemu_get_queue(n->nic);
3964-
if (!nc) {
3965-
return NULL;
3966-
}
3967-
3968-
net = get_vhost_net(nc->peer);
3969-
if (!net) {
3970-
return NULL;
3971-
}
3972-
3973-
return &net->dev;
3974-
}
3975-
39764065
static const VMStateDescription vmstate_virtio_net = {
39774066
.name = "virtio-net",
39784067
.minimum_version_id = VIRTIO_NET_VM_VERSION,

0 commit comments

Comments
 (0)