mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 22:02:02 +00:00
vdpa/mlx5: Fix mr->initialized semantics
[ Upstream commit9ee811009a
] The mr->initialized flag is shared between the control vq and data vq part of the mr init/uninit. But if the control vq and data vq get placed in different ASIDs, it can happen that initializing the control vq will prevent the data vq mr from being initialized. This patch consolidates the control and data vq init parts into their own init functions. The mr->initialized will now be used for the data vq only. The control vq currently doesn't need a flag. The uninitializing part is also taken care of: mlx5_vdpa_destroy_mr got split into data and control vq functions which are now also ASID aware. Fixes:8fcd20c307
("vdpa/mlx5: Support different address spaces for control and data") Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com> Reviewed-by: Eugenio Pérez <eperezma@redhat.com> Reviewed-by: Gal Pressman <gal@nvidia.com> Message-Id: <20230802171231.11001-3-dtatulea@nvidia.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
fa450621ef
commit
bfb5564d96
2 changed files with 75 additions and 31 deletions
|
@ -31,6 +31,7 @@ struct mlx5_vdpa_mr {
|
|||
struct list_head head;
|
||||
unsigned long num_directs;
|
||||
unsigned long num_klms;
|
||||
/* state of dvq mr */
|
||||
bool initialized;
|
||||
|
||||
/* serialize mkey creation and destruction */
|
||||
|
|
|
@ -489,60 +489,103 @@ static void destroy_user_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr
|
|||
}
|
||||
}
|
||||
|
||||
void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
|
||||
static void _mlx5_vdpa_destroy_cvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
|
||||
{
|
||||
if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
|
||||
return;
|
||||
|
||||
prune_iotlb(mvdev);
|
||||
}
|
||||
|
||||
static void _mlx5_vdpa_destroy_dvq_mr(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
|
||||
{
|
||||
struct mlx5_vdpa_mr *mr = &mvdev->mr;
|
||||
|
||||
mutex_lock(&mr->mkey_mtx);
|
||||
if (!mr->initialized)
|
||||
goto out;
|
||||
if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
|
||||
return;
|
||||
|
||||
if (!mr->initialized)
|
||||
return;
|
||||
|
||||
prune_iotlb(mvdev);
|
||||
if (mr->user_mr)
|
||||
destroy_user_mr(mvdev, mr);
|
||||
else
|
||||
destroy_dma_mr(mvdev, mr);
|
||||
|
||||
mr->initialized = false;
|
||||
out:
|
||||
}
|
||||
|
||||
static void mlx5_vdpa_destroy_mr_asid(struct mlx5_vdpa_dev *mvdev, unsigned int asid)
|
||||
{
|
||||
struct mlx5_vdpa_mr *mr = &mvdev->mr;
|
||||
|
||||
mutex_lock(&mr->mkey_mtx);
|
||||
|
||||
_mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
|
||||
_mlx5_vdpa_destroy_cvq_mr(mvdev, asid);
|
||||
|
||||
mutex_unlock(&mr->mkey_mtx);
|
||||
}
|
||||
|
||||
void mlx5_vdpa_destroy_mr(struct mlx5_vdpa_dev *mvdev)
|
||||
{
|
||||
mlx5_vdpa_destroy_mr_asid(mvdev, mvdev->group2asid[MLX5_VDPA_CVQ_GROUP]);
|
||||
mlx5_vdpa_destroy_mr_asid(mvdev, mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP]);
|
||||
}
|
||||
|
||||
static int _mlx5_vdpa_create_cvq_mr(struct mlx5_vdpa_dev *mvdev,
|
||||
struct vhost_iotlb *iotlb,
|
||||
unsigned int asid)
|
||||
{
|
||||
if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] != asid)
|
||||
return 0;
|
||||
|
||||
return dup_iotlb(mvdev, iotlb);
|
||||
}
|
||||
|
||||
static int _mlx5_vdpa_create_dvq_mr(struct mlx5_vdpa_dev *mvdev,
|
||||
struct vhost_iotlb *iotlb,
|
||||
unsigned int asid)
|
||||
{
|
||||
struct mlx5_vdpa_mr *mr = &mvdev->mr;
|
||||
int err;
|
||||
|
||||
if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] != asid)
|
||||
return 0;
|
||||
|
||||
if (mr->initialized)
|
||||
return 0;
|
||||
|
||||
if (iotlb)
|
||||
err = create_user_mr(mvdev, iotlb);
|
||||
else
|
||||
err = create_dma_mr(mvdev, mr);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mr->initialized = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev,
|
||||
struct vhost_iotlb *iotlb, unsigned int asid)
|
||||
{
|
||||
struct mlx5_vdpa_mr *mr = &mvdev->mr;
|
||||
int err;
|
||||
|
||||
if (mr->initialized)
|
||||
return 0;
|
||||
err = _mlx5_vdpa_create_dvq_mr(mvdev, iotlb, asid);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) {
|
||||
if (iotlb)
|
||||
err = create_user_mr(mvdev, iotlb);
|
||||
else
|
||||
err = create_dma_mr(mvdev, mr);
|
||||
err = _mlx5_vdpa_create_cvq_mr(mvdev, iotlb, asid);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (mvdev->group2asid[MLX5_VDPA_CVQ_GROUP] == asid) {
|
||||
err = dup_iotlb(mvdev, iotlb);
|
||||
if (err)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
mr->initialized = true;
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
if (mvdev->group2asid[MLX5_VDPA_DATAVQ_GROUP] == asid) {
|
||||
if (iotlb)
|
||||
destroy_user_mr(mvdev, mr);
|
||||
else
|
||||
destroy_dma_mr(mvdev, mr);
|
||||
}
|
||||
_mlx5_vdpa_destroy_dvq_mr(mvdev, asid);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue