Skip to content

Commit ffb1aae

Browse files
dtatuleamstsirkin
authored andcommitted
vdpa/mlx5: Pre-create hardware VQs at vdpa .dev_add time
Currently, hardware VQs are created right when the vdpa device gets into DRIVER_OK state. That is easier because most of the VQ state is known by then. This patch switches to creating all VQs and their associated resources at device creation time. The motivation is to reduce the vdpa device live migration downtime by moving the expensive operation of creating all the hardware VQs and their associated resources out of downtime on the destination VM. The VQs are now created in a blank state. The VQ configuration will happen later, on DRIVER_OK. Then the configuration will be applied when the VQs are moved to the Ready state. When .set_vq_ready() is called on a VQ before DRIVER_OK, special care is needed: now that the VQ is already created a resume_vq() will be triggered too early when no mr has been configured yet. Skip calling resume_vq() in this case, let it be handled during DRIVER_OK. For virtio-vdpa, the device configuration is done earlier during .vdpa_dev_add() by vdpa_register_device(). Avoid calling setup_vq_resources() a second time in that case. On a 64 CPU, 256 GB VM with 1 vDPA device of 16 VQps, the full VQ resource creation + resume time was ~370ms. Now it's down to 60 ms (only VQ config and resume). The measurements were done on a ConnectX6DX based vDPA device. Signed-off-by: Dragos Tatulea <[email protected]> Reviewed-by: Cosmin Ratiu <[email protected]> Message-Id: <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent 3b3adb3 commit ffb1aae

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

drivers/vdpa/mlx5/net/mlx5_vnet.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2444,7 +2444,7 @@ static void mlx5_vdpa_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool ready
24442444
mvq = &ndev->vqs[idx];
24452445
if (!ready) {
24462446
suspend_vq(ndev, mvq);
2447-
} else {
2447+
} else if (mvdev->status & VIRTIO_CONFIG_S_DRIVER_OK) {
24482448
if (resume_vq(ndev, mvq))
24492449
ready = false;
24502450
}
@@ -3078,10 +3078,18 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
30783078
goto err_setup;
30793079
}
30803080
register_link_notifier(ndev);
3081-
err = setup_vq_resources(ndev, true);
3082-
if (err) {
3083-
mlx5_vdpa_warn(mvdev, "failed to setup driver\n");
3084-
goto err_driver;
3081+
if (ndev->setup) {
3082+
err = resume_vqs(ndev);
3083+
if (err) {
3084+
mlx5_vdpa_warn(mvdev, "failed to resume VQs\n");
3085+
goto err_driver;
3086+
}
3087+
} else {
3088+
err = setup_vq_resources(ndev, true);
3089+
if (err) {
3090+
mlx5_vdpa_warn(mvdev, "failed to setup driver\n");
3091+
goto err_driver;
3092+
}
30853093
}
30863094
} else {
30873095
mlx5_vdpa_warn(mvdev, "did not expect DRIVER_OK to be cleared\n");
@@ -3142,6 +3150,7 @@ static int mlx5_vdpa_compat_reset(struct vdpa_device *vdev, u32 flags)
31423150
if (mlx5_vdpa_create_dma_mr(mvdev))
31433151
mlx5_vdpa_warn(mvdev, "create MR failed\n");
31443152
}
3153+
setup_vq_resources(ndev, false);
31453154
up_write(&ndev->reslock);
31463155

31473156
return 0;
@@ -3835,8 +3844,21 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name,
38353844
goto err_reg;
38363845

38373846
mgtdev->ndev = ndev;
3847+
3848+
/* For virtio-vdpa, the device was set up during device register. */
3849+
if (ndev->setup)
3850+
return 0;
3851+
3852+
down_write(&ndev->reslock);
3853+
err = setup_vq_resources(ndev, false);
3854+
up_write(&ndev->reslock);
3855+
if (err)
3856+
goto err_setup_vq_res;
3857+
38383858
return 0;
38393859

3860+
err_setup_vq_res:
3861+
_vdpa_unregister_device(&mvdev->vdev);
38403862
err_reg:
38413863
destroy_workqueue(mvdev->wq);
38423864
err_res2:
@@ -3862,6 +3884,11 @@ static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev *v_mdev, struct vdpa_device *
38623884

38633885
unregister_link_notifier(ndev);
38643886
_vdpa_unregister_device(dev);
3887+
3888+
down_write(&ndev->reslock);
3889+
teardown_vq_resources(ndev);
3890+
up_write(&ndev->reslock);
3891+
38653892
wq = mvdev->wq;
38663893
mvdev->wq = NULL;
38673894
destroy_workqueue(wq);

0 commit comments

Comments
 (0)