diff options
author | Dragos Tatulea | 2023-10-18 20:14:55 +0300 |
---|---|---|
committer | Michael S. Tsirkin | 2023-11-01 09:19:57 -0400 |
commit | 5dc31bd245a4fd7fe2d1fd79b7a2a81c96d6d33c (patch) | |
tree | 0df8f8fd7d0a79df4d5fdec6dbc12c91e7f79e94 /drivers/vdpa | |
parent | cf6e024cf7683551ae218ce9af56b82e68a0ef06 (diff) |
vdpa/mlx5: Update cvq iotlb mapping on ASID change
For the following sequence:
- cvq group is in ASID 0
- .set_map(1, cvq_iotlb)
- .set_group_asid(cvq_group, 1)
... the cvq mapping from ASID 0 will be used. This is not always correct
behaviour.
This patch adds support for the above mentioned flow by saving the iotlb
on each .set_map and updating the cvq iotlb with it on a cvq group change.
Acked-by: Jason Wang <jasowang@redhat.com>
Acked-by: Eugenio PĂ©rez <eperezma@redhat.com>
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Message-Id: <20231018171456.1624030-18-dtatulea@nvidia.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Si-Wei Liu <si-wei.liu@oracle.com>
Tested-by: Si-Wei Liu <si-wei.liu@oracle.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Diffstat (limited to 'drivers/vdpa')
-rw-r--r-- | drivers/vdpa/mlx5/core/mlx5_vdpa.h | 2 | ||||
-rw-r--r-- | drivers/vdpa/mlx5/core/mr.c | 26 | ||||
-rw-r--r-- | drivers/vdpa/mlx5/net/mlx5_vnet.c | 9 |
3 files changed, 36 insertions, 1 deletions
diff --git a/drivers/vdpa/mlx5/core/mlx5_vdpa.h b/drivers/vdpa/mlx5/core/mlx5_vdpa.h index ae09296f4270..db988ced5a5d 100644 --- a/drivers/vdpa/mlx5/core/mlx5_vdpa.h +++ b/drivers/vdpa/mlx5/core/mlx5_vdpa.h @@ -32,6 +32,8 @@ struct mlx5_vdpa_mr { unsigned long num_directs; unsigned long num_klms; + struct vhost_iotlb *iotlb; + bool user_mr; }; diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c index 4a3df865df40..66530e28f327 100644 --- a/drivers/vdpa/mlx5/core/mr.c +++ b/drivers/vdpa/mlx5/core/mr.c @@ -502,6 +502,8 @@ static void _mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_ destroy_user_mr(mvdev, mr); else destroy_dma_mr(mvdev, mr); + + vhost_iotlb_free(mr->iotlb); } void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev, @@ -561,6 +563,30 @@ static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, else err = create_dma_mr(mvdev, mr); + if (err) + return err; + + mr->iotlb = vhost_iotlb_alloc(0, 0); + if (!mr->iotlb) { + err = -ENOMEM; + goto err_mr; + } + + err = dup_iotlb(mr->iotlb, iotlb); + if (err) + goto err_iotlb; + + return 0; + +err_iotlb: + vhost_iotlb_free(mr->iotlb); + +err_mr: + if (iotlb) + destroy_user_mr(mvdev, mr); + else + destroy_dma_mr(mvdev, mr); + return err; } diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index 63aa6ec4ef88..55f9233dedf1 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -3203,12 +3203,19 @@ static int mlx5_set_group_asid(struct vdpa_device *vdev, u32 group, unsigned int asid) { struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev); + int err = 0; if (group >= MLX5_VDPA_NUMVQ_GROUPS) return -EINVAL; mvdev->group2asid[group] = asid; - return 0; + + mutex_lock(&mvdev->mr_mtx); + if (group == MLX5_VDPA_CVQ_GROUP && mvdev->mr[asid]) + err = mlx5_vdpa_update_cvq_iotlb(mvdev, mvdev->mr[asid]->iotlb, asid); + mutex_unlock(&mvdev->mr_mtx); + + return err; } static const struct vdpa_config_ops mlx5_vdpa_ops = { |