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,
|
||||
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,
|
||||
NULL);
|
||||
name);
|
||||
if (IS_ERR(ndev))
|
||||
return PTR_ERR(ndev);
|
||||
|
||||
|
@ -2017,11 +2026,12 @@ static int mlx5v_probe(struct auxiliary_device *adev,
|
|||
if (err)
|
||||
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)
|
||||
goto err_reg;
|
||||
|
||||
dev_set_drvdata(&adev->dev, ndev);
|
||||
mgtdev->ndev = ndev;
|
||||
return 0;
|
||||
|
||||
err_reg:
|
||||
|
@ -2034,11 +2044,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(mgtdev);
|
||||
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[] = {
|
||||
|
|
Loading…
Reference in New Issue