Message ID | 20240626-stage-vdpa-vq-precreate-v2-15-560c491078df@nvidia.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | vdpa/mlx5: Pre-create HW VQs to reduce LM downtime | expand |
On Wed, Jun 26, 2024 at 12:28 PM Dragos Tatulea <dtatulea@nvidia.com> wrote: > > Based on the filled flag, create VQs that are filled or blank. > Blank VQs will be filled in later through VQ modify. > > Downstream patches will make use of this to pre-create blank VQs at > vdpa device creation. > s/Downstream/Later/ ? > Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com> > Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com> Acked-by: Eugenio Pérez <eperezma@redhat.com> > --- > drivers/vdpa/mlx5/net/mlx5_vnet.c | 85 +++++++++++++++++++++++++-------------- > 1 file changed, 55 insertions(+), 30 deletions(-) > > diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c > index a8ac542f30f7..0a62ce0b4af8 100644 > --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c > +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c > @@ -158,7 +158,7 @@ static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) > > static void free_fixed_resources(struct mlx5_vdpa_net *ndev); > static void mvqs_set_defaults(struct mlx5_vdpa_net *ndev); > -static int setup_vq_resources(struct mlx5_vdpa_net *ndev); > +static int setup_vq_resources(struct mlx5_vdpa_net *ndev, bool filled); > static void teardown_vq_resources(struct mlx5_vdpa_net *ndev); > > static bool mlx5_vdpa_debug; > @@ -874,13 +874,16 @@ static bool msix_mode_supported(struct mlx5_vdpa_dev *mvdev) > pci_msix_can_alloc_dyn(mvdev->mdev->pdev); > } > > -static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq) > +static int create_virtqueue(struct mlx5_vdpa_net *ndev, > + struct mlx5_vdpa_virtqueue *mvq, > + bool filled) > { > int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in); > u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {}; > struct mlx5_vdpa_dev *mvdev = &ndev->mvdev; > struct mlx5_vdpa_mr *vq_mr; > struct mlx5_vdpa_mr *vq_desc_mr; > + u64 features = filled ? mvdev->actual_features : mvdev->mlx_features; > void *obj_context; > u16 mlx_features; > void *cmd_hdr; > @@ -898,7 +901,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque > goto err_alloc; > } > > - mlx_features = get_features(ndev->mvdev.actual_features); > + mlx_features = get_features(features); > cmd_hdr = MLX5_ADDR_OF(create_virtio_net_q_in, in, general_obj_in_cmd_hdr); > > MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); > @@ -906,8 +909,6 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque > MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid); > > obj_context = MLX5_ADDR_OF(create_virtio_net_q_in, in, obj_context); > - MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx); > - MLX5_SET(virtio_net_q_object, obj_context, hw_used_index, mvq->used_idx); > MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_12_3, > mlx_features >> 3); > MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_2_0, > @@ -929,17 +930,36 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque > MLX5_SET(virtio_q, vq_ctx, queue_index, mvq->index); > MLX5_SET(virtio_q, vq_ctx, queue_size, mvq->num_ent); > MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0, > - !!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_F_VERSION_1))); > - MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr); > - MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr); > - MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr); > - vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]]; > - if (vq_mr) > - MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey); > - > - vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]]; > - if (vq_desc_mr && MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) > - MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey); > + !!(features & BIT_ULL(VIRTIO_F_VERSION_1))); > + > + if (filled) { > + MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx); > + MLX5_SET(virtio_net_q_object, obj_context, hw_used_index, mvq->used_idx); > + > + MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr); > + MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr); > + MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr); > + > + vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]]; > + if (vq_mr) > + MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey); > + > + vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]]; > + if (vq_desc_mr && > + MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) > + MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey); > + } else { > + /* If there is no mr update, make sure that the existing ones are set > + * modify to ready. > + */ > + vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]]; > + if (vq_mr) > + mvq->modified_fields |= MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_MKEY; > + > + vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]]; > + if (vq_desc_mr) > + mvq->modified_fields |= MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY; > + } > > MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id); > MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size); > @@ -959,12 +979,15 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque > kfree(in); > mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); > > - mlx5_vdpa_get_mr(mvdev, vq_mr); > - mvq->vq_mr = vq_mr; > + if (filled) { > + mlx5_vdpa_get_mr(mvdev, vq_mr); > + mvq->vq_mr = vq_mr; > > - if (vq_desc_mr && MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) { > - mlx5_vdpa_get_mr(mvdev, vq_desc_mr); > - mvq->desc_mr = vq_desc_mr; > + if (vq_desc_mr && > + MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) { > + mlx5_vdpa_get_mr(mvdev, vq_desc_mr); > + mvq->desc_mr = vq_desc_mr; > + } > } > > return 0; > @@ -1442,7 +1465,9 @@ static void dealloc_vector(struct mlx5_vdpa_net *ndev, > } > } > > -static int setup_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq) > +static int setup_vq(struct mlx5_vdpa_net *ndev, > + struct mlx5_vdpa_virtqueue *mvq, > + bool filled) > { > u16 idx = mvq->index; > int err; > @@ -1471,7 +1496,7 @@ static int setup_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq) > goto err_connect; > > alloc_vector(ndev, mvq); > - err = create_virtqueue(ndev, mvq); > + err = create_virtqueue(ndev, mvq, filled); > if (err) > goto err_vq; > > @@ -2062,7 +2087,7 @@ static int change_num_qps(struct mlx5_vdpa_dev *mvdev, int newqps) > } else { > ndev->cur_num_vqs = 2 * newqps; > for (i = cur_qps * 2; i < 2 * newqps; i++) { > - err = setup_vq(ndev, &ndev->vqs[i]); > + err = setup_vq(ndev, &ndev->vqs[i], true); > if (err) > goto clean_added; > } > @@ -2558,14 +2583,14 @@ static int verify_driver_features(struct mlx5_vdpa_dev *mvdev, u64 features) > return 0; > } > > -static int setup_virtqueues(struct mlx5_vdpa_dev *mvdev) > +static int setup_virtqueues(struct mlx5_vdpa_dev *mvdev, bool filled) > { > struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); > int err; > int i; > > for (i = 0; i < mvdev->max_vqs; i++) { > - err = setup_vq(ndev, &ndev->vqs[i]); > + err = setup_vq(ndev, &ndev->vqs[i], filled); > if (err) > goto err_vq; > } > @@ -2877,7 +2902,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, > > if (teardown) { > restore_channels_info(ndev); > - err = setup_vq_resources(ndev); > + err = setup_vq_resources(ndev, true); > if (err) > return err; > } > @@ -2888,7 +2913,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, > } > > /* reslock must be held for this function */ > -static int setup_vq_resources(struct mlx5_vdpa_net *ndev) > +static int setup_vq_resources(struct mlx5_vdpa_net *ndev, bool filled) > { > struct mlx5_vdpa_dev *mvdev = &ndev->mvdev; > int err; > @@ -2906,7 +2931,7 @@ static int setup_vq_resources(struct mlx5_vdpa_net *ndev) > if (err) > goto err_setup; > > - err = setup_virtqueues(mvdev); > + err = setup_virtqueues(mvdev, filled); > if (err) { > mlx5_vdpa_warn(mvdev, "setup_virtqueues\n"); > goto err_setup; > @@ -3000,7 +3025,7 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status) > goto err_setup; > } > register_link_notifier(ndev); > - err = setup_vq_resources(ndev); > + err = setup_vq_resources(ndev, true); > if (err) { > mlx5_vdpa_warn(mvdev, "failed to setup driver\n"); > goto err_driver; > > -- > 2.45.1 >
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index a8ac542f30f7..0a62ce0b4af8 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -158,7 +158,7 @@ static bool is_index_valid(struct mlx5_vdpa_dev *mvdev, u16 idx) static void free_fixed_resources(struct mlx5_vdpa_net *ndev); static void mvqs_set_defaults(struct mlx5_vdpa_net *ndev); -static int setup_vq_resources(struct mlx5_vdpa_net *ndev); +static int setup_vq_resources(struct mlx5_vdpa_net *ndev, bool filled); static void teardown_vq_resources(struct mlx5_vdpa_net *ndev); static bool mlx5_vdpa_debug; @@ -874,13 +874,16 @@ static bool msix_mode_supported(struct mlx5_vdpa_dev *mvdev) pci_msix_can_alloc_dyn(mvdev->mdev->pdev); } -static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq) +static int create_virtqueue(struct mlx5_vdpa_net *ndev, + struct mlx5_vdpa_virtqueue *mvq, + bool filled) { int inlen = MLX5_ST_SZ_BYTES(create_virtio_net_q_in); u32 out[MLX5_ST_SZ_DW(create_virtio_net_q_out)] = {}; struct mlx5_vdpa_dev *mvdev = &ndev->mvdev; struct mlx5_vdpa_mr *vq_mr; struct mlx5_vdpa_mr *vq_desc_mr; + u64 features = filled ? mvdev->actual_features : mvdev->mlx_features; void *obj_context; u16 mlx_features; void *cmd_hdr; @@ -898,7 +901,7 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque goto err_alloc; } - mlx_features = get_features(ndev->mvdev.actual_features); + mlx_features = get_features(features); cmd_hdr = MLX5_ADDR_OF(create_virtio_net_q_in, in, general_obj_in_cmd_hdr); MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); @@ -906,8 +909,6 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque MLX5_SET(general_obj_in_cmd_hdr, cmd_hdr, uid, ndev->mvdev.res.uid); obj_context = MLX5_ADDR_OF(create_virtio_net_q_in, in, obj_context); - MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx); - MLX5_SET(virtio_net_q_object, obj_context, hw_used_index, mvq->used_idx); MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_12_3, mlx_features >> 3); MLX5_SET(virtio_net_q_object, obj_context, queue_feature_bit_mask_2_0, @@ -929,17 +930,36 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque MLX5_SET(virtio_q, vq_ctx, queue_index, mvq->index); MLX5_SET(virtio_q, vq_ctx, queue_size, mvq->num_ent); MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0, - !!(ndev->mvdev.actual_features & BIT_ULL(VIRTIO_F_VERSION_1))); - MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr); - MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr); - MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr); - vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]]; - if (vq_mr) - MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey); - - vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]]; - if (vq_desc_mr && MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) - MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey); + !!(features & BIT_ULL(VIRTIO_F_VERSION_1))); + + if (filled) { + MLX5_SET(virtio_net_q_object, obj_context, hw_available_index, mvq->avail_idx); + MLX5_SET(virtio_net_q_object, obj_context, hw_used_index, mvq->used_idx); + + MLX5_SET64(virtio_q, vq_ctx, desc_addr, mvq->desc_addr); + MLX5_SET64(virtio_q, vq_ctx, used_addr, mvq->device_addr); + MLX5_SET64(virtio_q, vq_ctx, available_addr, mvq->driver_addr); + + vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]]; + if (vq_mr) + MLX5_SET(virtio_q, vq_ctx, virtio_q_mkey, vq_mr->mkey); + + vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]]; + if (vq_desc_mr && + MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) + MLX5_SET(virtio_q, vq_ctx, desc_group_mkey, vq_desc_mr->mkey); + } else { + /* If there is no mr update, make sure that the existing ones are set + * modify to ready. + */ + vq_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]]; + if (vq_mr) + mvq->modified_fields |= MLX5_VIRTQ_MODIFY_MASK_VIRTIO_Q_MKEY; + + vq_desc_mr = mvdev->mr[mvdev->group2asid[MLX5_VDPA_DATAVQ_DESC_GROUP]]; + if (vq_desc_mr) + mvq->modified_fields |= MLX5_VIRTQ_MODIFY_MASK_DESC_GROUP_MKEY; + } MLX5_SET(virtio_q, vq_ctx, umem_1_id, mvq->umem1.id); MLX5_SET(virtio_q, vq_ctx, umem_1_size, mvq->umem1.size); @@ -959,12 +979,15 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque kfree(in); mvq->virtq_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); - mlx5_vdpa_get_mr(mvdev, vq_mr); - mvq->vq_mr = vq_mr; + if (filled) { + mlx5_vdpa_get_mr(mvdev, vq_mr); + mvq->vq_mr = vq_mr; - if (vq_desc_mr && MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) { - mlx5_vdpa_get_mr(mvdev, vq_desc_mr); - mvq->desc_mr = vq_desc_mr; + if (vq_desc_mr && + MLX5_CAP_DEV_VDPA_EMULATION(mvdev->mdev, desc_group_mkey_supported)) { + mlx5_vdpa_get_mr(mvdev, vq_desc_mr); + mvq->desc_mr = vq_desc_mr; + } } return 0; @@ -1442,7 +1465,9 @@ static void dealloc_vector(struct mlx5_vdpa_net *ndev, } } -static int setup_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq) +static int setup_vq(struct mlx5_vdpa_net *ndev, + struct mlx5_vdpa_virtqueue *mvq, + bool filled) { u16 idx = mvq->index; int err; @@ -1471,7 +1496,7 @@ static int setup_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq) goto err_connect; alloc_vector(ndev, mvq); - err = create_virtqueue(ndev, mvq); + err = create_virtqueue(ndev, mvq, filled); if (err) goto err_vq; @@ -2062,7 +2087,7 @@ static int change_num_qps(struct mlx5_vdpa_dev *mvdev, int newqps) } else { ndev->cur_num_vqs = 2 * newqps; for (i = cur_qps * 2; i < 2 * newqps; i++) { - err = setup_vq(ndev, &ndev->vqs[i]); + err = setup_vq(ndev, &ndev->vqs[i], true); if (err) goto clean_added; } @@ -2558,14 +2583,14 @@ static int verify_driver_features(struct mlx5_vdpa_dev *mvdev, u64 features) return 0; } -static int setup_virtqueues(struct mlx5_vdpa_dev *mvdev) +static int setup_virtqueues(struct mlx5_vdpa_dev *mvdev, bool filled) { struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev); int err; int i; for (i = 0; i < mvdev->max_vqs; i++) { - err = setup_vq(ndev, &ndev->vqs[i]); + err = setup_vq(ndev, &ndev->vqs[i], filled); if (err) goto err_vq; } @@ -2877,7 +2902,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, if (teardown) { restore_channels_info(ndev); - err = setup_vq_resources(ndev); + err = setup_vq_resources(ndev, true); if (err) return err; } @@ -2888,7 +2913,7 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_dev *mvdev, } /* reslock must be held for this function */ -static int setup_vq_resources(struct mlx5_vdpa_net *ndev) +static int setup_vq_resources(struct mlx5_vdpa_net *ndev, bool filled) { struct mlx5_vdpa_dev *mvdev = &ndev->mvdev; int err; @@ -2906,7 +2931,7 @@ static int setup_vq_resources(struct mlx5_vdpa_net *ndev) if (err) goto err_setup; - err = setup_virtqueues(mvdev); + err = setup_virtqueues(mvdev, filled); if (err) { mlx5_vdpa_warn(mvdev, "setup_virtqueues\n"); goto err_setup; @@ -3000,7 +3025,7 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status) goto err_setup; } register_link_notifier(ndev); - err = setup_vq_resources(ndev); + err = setup_vq_resources(ndev, true); if (err) { mlx5_vdpa_warn(mvdev, "failed to setup driver\n"); goto err_driver;