mirror of https://gitee.com/openkylin/linux.git
vdpa/mlx5: Enable user to add/delete vdpa device
Allow to control vdpa device creation and destruction using the vdpa management tool. Examples: 1. List the management devices $ vdpa mgmtdev show pci/0000:3b:00.1: supported_classes net 2. Create vdpa instance $ vdpa dev add mgmtdev pci/0000:3b:00.1 name vdpa0 3. Show vdpa devices $ vdpa dev show vdpa0: type network mgmtdev pci/0000:3b:00.1 vendor_id 5555 max_vqs 16 \ max_vq_size 256 Signed-off-by: Eli Cohen <elic@nvidia.com> Reviewed-by: Parav Pandit <parav@nvidia.com> Acked-by: Jason Wang <jasowang@redhat.com> Link: https://lore.kernel.org/r/20210408091320.4600-1-elic@nvidia.com Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
64b9f64f80
commit
58926c8aab
|
@ -1974,23 +1974,32 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlx5v_probe(struct auxiliary_device *adev,
|
struct mlx5_vdpa_mgmtdev {
|
||||||
const struct auxiliary_device_id *id)
|
struct vdpa_mgmt_dev mgtdev;
|
||||||
|
struct mlx5_adev *madev;
|
||||||
|
struct mlx5_vdpa_net *ndev;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name)
|
||||||
{
|
{
|
||||||
struct mlx5_adev *madev = container_of(adev, struct mlx5_adev, adev);
|
struct mlx5_vdpa_mgmtdev *mgtdev = container_of(v_mdev, struct mlx5_vdpa_mgmtdev, mgtdev);
|
||||||
struct mlx5_core_dev *mdev = madev->mdev;
|
|
||||||
struct virtio_net_config *config;
|
struct virtio_net_config *config;
|
||||||
struct mlx5_vdpa_dev *mvdev;
|
struct mlx5_vdpa_dev *mvdev;
|
||||||
struct mlx5_vdpa_net *ndev;
|
struct mlx5_vdpa_net *ndev;
|
||||||
|
struct mlx5_core_dev *mdev;
|
||||||
u32 max_vqs;
|
u32 max_vqs;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (mgtdev->ndev)
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
|
mdev = mgtdev->madev->mdev;
|
||||||
/* we save one virtqueue for control virtqueue should we require it */
|
/* we save one virtqueue for control virtqueue should we require it */
|
||||||
max_vqs = MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues);
|
max_vqs = MLX5_CAP_DEV_VDPA_EMULATION(mdev, max_num_virtio_queues);
|
||||||
max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
|
max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
|
||||||
|
|
||||||
ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
|
ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
|
||||||
NULL);
|
name);
|
||||||
if (IS_ERR(ndev))
|
if (IS_ERR(ndev))
|
||||||
return PTR_ERR(ndev);
|
return PTR_ERR(ndev);
|
||||||
|
|
||||||
|
@ -2017,11 +2026,12 @@ static int mlx5v_probe(struct auxiliary_device *adev,
|
||||||
if (err)
|
if (err)
|
||||||
goto err_res;
|
goto err_res;
|
||||||
|
|
||||||
err = vdpa_register_device(&mvdev->vdev, 2 * mlx5_vdpa_max_qps(max_vqs));
|
mvdev->vdev.mdev = &mgtdev->mgtdev;
|
||||||
|
err = _vdpa_register_device(&mvdev->vdev, 2 * mlx5_vdpa_max_qps(max_vqs));
|
||||||
if (err)
|
if (err)
|
||||||
goto err_reg;
|
goto err_reg;
|
||||||
|
|
||||||
dev_set_drvdata(&adev->dev, ndev);
|
mgtdev->ndev = ndev;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_reg:
|
err_reg:
|
||||||
|
@ -2034,11 +2044,62 @@ static int mlx5v_probe(struct auxiliary_device *adev,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev *v_mdev, struct vdpa_device *dev)
|
||||||
|
{
|
||||||
|
struct mlx5_vdpa_mgmtdev *mgtdev = container_of(v_mdev, struct mlx5_vdpa_mgmtdev, mgtdev);
|
||||||
|
|
||||||
|
_vdpa_unregister_device(dev);
|
||||||
|
mgtdev->ndev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct vdpa_mgmtdev_ops mdev_ops = {
|
||||||
|
.dev_add = mlx5_vdpa_dev_add,
|
||||||
|
.dev_del = mlx5_vdpa_dev_del,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct virtio_device_id id_table[] = {
|
||||||
|
{ VIRTIO_ID_NET, VIRTIO_DEV_ANY_ID },
|
||||||
|
{ 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mlx5v_probe(struct auxiliary_device *adev,
|
||||||
|
const struct auxiliary_device_id *id)
|
||||||
|
|
||||||
|
{
|
||||||
|
struct mlx5_adev *madev = container_of(adev, struct mlx5_adev, adev);
|
||||||
|
struct mlx5_core_dev *mdev = madev->mdev;
|
||||||
|
struct mlx5_vdpa_mgmtdev *mgtdev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
mgtdev = kzalloc(sizeof(*mgtdev), GFP_KERNEL);
|
||||||
|
if (!mgtdev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mgtdev->mgtdev.ops = &mdev_ops;
|
||||||
|
mgtdev->mgtdev.device = mdev->device;
|
||||||
|
mgtdev->mgtdev.id_table = id_table;
|
||||||
|
mgtdev->madev = madev;
|
||||||
|
|
||||||
|
err = vdpa_mgmtdev_register(&mgtdev->mgtdev);
|
||||||
|
if (err)
|
||||||
|
goto reg_err;
|
||||||
|
|
||||||
|
dev_set_drvdata(&adev->dev, mgtdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
reg_err:
|
||||||
|
kfree(mgtdev);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static void mlx5v_remove(struct auxiliary_device *adev)
|
static void mlx5v_remove(struct auxiliary_device *adev)
|
||||||
{
|
{
|
||||||
struct mlx5_vdpa_dev *mvdev = dev_get_drvdata(&adev->dev);
|
struct mlx5_vdpa_mgmtdev *mgtdev;
|
||||||
|
|
||||||
vdpa_unregister_device(&mvdev->vdev);
|
mgtdev = dev_get_drvdata(&adev->dev);
|
||||||
|
vdpa_mgmtdev_unregister(&mgtdev->mgtdev);
|
||||||
|
kfree(mgtdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct auxiliary_device_id mlx5v_id_table[] = {
|
static const struct auxiliary_device_id mlx5v_id_table[] = {
|
||||||
|
|
Loading…
Reference in New Issue