From: Saeed Mahameed <saeedm@xxxxxxxxxxxx> __mlx5_ib_add didn't allocate ib_device, this means __mlx5_ib_remove shouldn't free it, hence make the alloc/dealloc symmetric. Put dealloc_device outside __mlx5_ib_remove and convert __mlx5_ib_add to return int value rather than dev pointer on success and null on failure. Signed-off-by: Saeed Mahameed <saeedm@xxxxxxxxxxxx> Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> --- drivers/infiniband/hw/mlx5/ib_rep.c | 9 +++++++-- drivers/infiniband/hw/mlx5/main.c | 23 +++++++++++++++-------- drivers/infiniband/hw/mlx5/mlx5_ib.h | 4 ++-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/ib_rep.c b/drivers/infiniband/hw/mlx5/ib_rep.c index 8a682d86d634..5ee383b0fc32 100644 --- a/drivers/infiniband/hw/mlx5/ib_rep.c +++ b/drivers/infiniband/hw/mlx5/ib_rep.c @@ -61,6 +61,7 @@ static int mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) { struct mlx5_ib_dev *ibdev; + int err; ibdev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*ibdev)); if (!ibdev) @@ -70,8 +71,11 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ibdev->mdev = dev; ibdev->num_ports = max(MLX5_CAP_GEN(dev, num_ports), MLX5_CAP_GEN(dev, num_vhca_ports)); - if (!__mlx5_ib_add(ibdev, &rep_profile)) - return -EINVAL; + err = __mlx5_ib_add(ibdev, &rep_profile); + if (err) { + ib_dealloc_device((struct ib_device *)dev); + return err; + } rep->rep_if[REP_IB].priv = ibdev; @@ -88,6 +92,7 @@ mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep *rep) dev = mlx5_ib_rep_to_dev(rep); __mlx5_ib_remove(dev, dev->profile, MLX5_IB_STAGE_MAX); + ib_dealloc_device((struct ib_device *)dev); rep->rep_if[REP_IB].priv = NULL; } diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 2b09e6896e5a..0c877ffa44f4 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -6256,12 +6256,10 @@ void __mlx5_ib_remove(struct mlx5_ib_dev *dev, if (profile->stage[stage].cleanup) profile->stage[stage].cleanup(dev); } - - ib_dealloc_device((struct ib_device *)dev); } -void *__mlx5_ib_add(struct mlx5_ib_dev *dev, - const struct mlx5_ib_profile *profile) +int __mlx5_ib_add(struct mlx5_ib_dev *dev, + const struct mlx5_ib_profile *profile) { int err; int i; @@ -6277,12 +6275,12 @@ void *__mlx5_ib_add(struct mlx5_ib_dev *dev, dev->profile = profile; dev->ib_active = true; - return dev; + return 0; err_out: __mlx5_ib_remove(dev, profile, i); - return NULL; + return err; } static const struct mlx5_ib_profile pf_profile = { @@ -6435,6 +6433,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) enum rdma_link_layer ll; struct mlx5_ib_dev *dev; int port_type_cap; + int err; printk_once(KERN_INFO "%s", mlx5_version); @@ -6456,10 +6455,17 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) mlx5_ib_eswitch_mode(mdev->priv.eswitch) == SRIOV_OFFLOADS) { dev->rep = mlx5_ib_vport_rep(mdev->priv.eswitch, 0); - return __mlx5_ib_add(dev, &nic_rep_profile); + err = __mlx5_ib_add(dev, &nic_rep_profile); + } else { + err = __mlx5_ib_add(dev, &pf_profile); + } + + if (err) { + ib_dealloc_device((struct ib_device *)dev); + dev = NULL; } - return __mlx5_ib_add(dev, &pf_profile); + return dev; } static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context) @@ -6479,6 +6485,7 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context) dev = context; __mlx5_ib_remove(dev, dev->profile, MLX5_IB_STAGE_MAX); + ib_dealloc_device((struct ib_device *)dev); } static struct mlx5_interface mlx5_ib_interface = { diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index 24cb2f793210..4ad493f581de 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -1222,8 +1222,8 @@ int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev); void __mlx5_ib_remove(struct mlx5_ib_dev *dev, const struct mlx5_ib_profile *profile, int stage); -void *__mlx5_ib_add(struct mlx5_ib_dev *dev, - const struct mlx5_ib_profile *profile); +int __mlx5_ib_add(struct mlx5_ib_dev *dev, + const struct mlx5_ib_profile *profile); int mlx5_ib_get_vf_config(struct ib_device *device, int vf, u8 port, struct ifla_vf_info *info); -- 2.19.1