Commit 58926c8a authored by Eli Cohen's avatar Eli Cohen Committed by Michael S. Tsirkin

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: default avatarEli Cohen <elic@nvidia.com>
Reviewed-by: default avatarParav Pandit <parav@nvidia.com>
Acked-by: default avatarJason Wang <jasowang@redhat.com>
Link: https://lore.kernel.org/r/20210408091320.4600-1-elic@nvidia.comSigned-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 64b9f64f
...@@ -1974,23 +1974,32 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev) ...@@ -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, ...@@ -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, ...@@ -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[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment