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 <e...@nvidia.com>
Reviewed-by: Parav Pandit <pa...@nvidia.com>
---
v0->v1:
set mgtdev->ndev NULL on dev delete 

 drivers/vdpa/mlx5/net/mlx5_vnet.c | 79 +++++++++++++++++++++++++++----
 1 file changed, 70 insertions(+), 9 deletions(-)

diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c 
b/drivers/vdpa/mlx5/net/mlx5_vnet.c
index a51b0f86afe2..08fb481ddc4f 100644
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
@@ -1974,23 +1974,32 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev)
        }
 }
 
-static int mlx5v_probe(struct auxiliary_device *adev,
-                      const struct auxiliary_device_id *id)
+struct mlx5_vdpa_mgmtdev {
+       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_core_dev *mdev = madev->mdev;
+       struct mlx5_vdpa_mgmtdev *mgtdev = container_of(v_mdev, struct 
mlx5_vdpa_mgmtdev, mgtdev);
        struct virtio_net_config *config;
        struct mlx5_vdpa_dev *mvdev;
        struct mlx5_vdpa_net *ndev;
+       struct mlx5_core_dev *mdev;
        u32 max_vqs;
        int err;
 
+       if (mgtdev->ndev)
+               return -ENOSPC;
+
+       mdev = mgtdev->madev->mdev;
        /* 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 = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);
 
        ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, 
mdev->device, &mlx5_vdpa_ops,
-                                2 * mlx5_vdpa_max_qps(max_vqs), NULL);
+                                2 * mlx5_vdpa_max_qps(max_vqs), name);
        if (IS_ERR(ndev))
                return PTR_ERR(ndev);
 
@@ -2018,11 +2027,12 @@ static int mlx5v_probe(struct auxiliary_device *adev,
        if (err)
                goto err_res;
 
-       err = vdpa_register_device(&mvdev->vdev);
+       mvdev->vdev.mdev = &mgtdev->mgtdev;
+       err = _vdpa_register_device(&mvdev->vdev);
        if (err)
                goto err_reg;
 
-       dev_set_drvdata(&adev->dev, ndev);
+       mgtdev->ndev = ndev;
        return 0;
 
 err_reg:
@@ -2035,11 +2045,62 @@ static int mlx5v_probe(struct auxiliary_device *adev,
        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(mdev);
+       return err;
+}
+
 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[] = {
-- 
2.29.2

Reply via email to