On Mon, 2019-07-22 at 17:01 +0200, Arnd Bergmann wrote:
> The mlx4_dev_cap and mlx4_init_hca_param are really too large
> to be put on the kernel stack, as shown by this clang warning:
> 
> drivers/net/ethernet/mellanox/mlx4/main.c:3304:12: error: stack frame
> size of 1088 bytes in function 'mlx4_load_one' [-Werror,-Wframe-
> larger-than=]
> 
> With gcc, the problem is the same, but it does not warn because
> it does not inline this function, and therefore stays just below
> the warning limit, while clang is just above it.
> 
> Use kzalloc for dynamic allocation instead of putting them
> on stack. This gets the combined stack frame down to 424 bytes.
> 
> Signed-off-by: Arnd Bergmann <a...@arndb.de>

Reviewed-by: Saeed Mahameed <sae...@mellanox.com>

> ---
>  drivers/net/ethernet/mellanox/mlx4/main.c | 66 +++++++++++++------
> ----
>  1 file changed, 39 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c
> b/drivers/net/ethernet/mellanox/mlx4/main.c
> index 1f6e16d5ea6b..07c204bd3fc4 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/main.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/main.c
> @@ -2292,23 +2292,31 @@ static int mlx4_init_fw(struct mlx4_dev *dev)
>  static int mlx4_init_hca(struct mlx4_dev *dev)
>  {
>       struct mlx4_priv          *priv = mlx4_priv(dev);
> +     struct mlx4_init_hca_param *init_hca = NULL;
> +     struct mlx4_dev_cap       *dev_cap = NULL;
>       struct mlx4_adapter        adapter;
> -     struct mlx4_dev_cap        dev_cap;
>       struct mlx4_profile        profile;
> -     struct mlx4_init_hca_param init_hca;
>       u64 icm_size;
>       struct mlx4_config_dev_params params;
>       int err;
>  
>       if (!mlx4_is_slave(dev)) {
> -             err = mlx4_dev_cap(dev, &dev_cap);
> +             dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL);
> +             init_hca = kzalloc(sizeof(*init_hca), GFP_KERNEL);
> +
> +             if (!dev_cap || !init_hca) {
> +                     err = -ENOMEM;
> +                     goto out_free;
> +             }
> +
> +             err = mlx4_dev_cap(dev, dev_cap);
>               if (err) {
>                       mlx4_err(dev, "QUERY_DEV_CAP command failed,
> aborting\n");
> -                     return err;
> +                     goto out_free;
>               }
>  
> -             choose_steering_mode(dev, &dev_cap);
> -             choose_tunnel_offload_mode(dev, &dev_cap);
> +             choose_steering_mode(dev, dev_cap);
> +             choose_tunnel_offload_mode(dev, dev_cap);
>  
>               if (dev->caps.dmfs_high_steer_mode ==
> MLX4_STEERING_DMFS_A0_STATIC &&
>                   mlx4_is_master(dev))
> @@ -2331,48 +2339,48 @@ static int mlx4_init_hca(struct mlx4_dev
> *dev)
>                   MLX4_STEERING_MODE_DEVICE_MANAGED)
>                       profile.num_mcg = MLX4_FS_NUM_MCG;
>  
> -             icm_size = mlx4_make_profile(dev, &profile, &dev_cap,
> -                                          &init_hca);
> +             icm_size = mlx4_make_profile(dev, &profile, dev_cap,
> +                                          init_hca);
>               if ((long long) icm_size < 0) {
>                       err = icm_size;
> -                     return err;
> +                     goto out_free;
>               }
>  
>               dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev-
> >caps.num_mpts))) - 1;
>  
>               if (enable_4k_uar || !dev->persist->num_vfs) {
> -                     init_hca.log_uar_sz = ilog2(dev->caps.num_uars) 
> +
> +                     init_hca->log_uar_sz = ilog2(dev-
> >caps.num_uars) +
>                                                   PAGE_SHIFT -
> DEFAULT_UAR_PAGE_SHIFT;
> -                     init_hca.uar_page_sz = DEFAULT_UAR_PAGE_SHIFT -
> 12;
> +                     init_hca->uar_page_sz = DEFAULT_UAR_PAGE_SHIFT
> - 12;
>               } else {
> -                     init_hca.log_uar_sz = ilog2(dev-
> >caps.num_uars);
> -                     init_hca.uar_page_sz = PAGE_SHIFT - 12;
> +                     init_hca->log_uar_sz = ilog2(dev-
> >caps.num_uars);
> +                     init_hca->uar_page_sz = PAGE_SHIFT - 12;
>               }
>  
> -             init_hca.mw_enabled = 0;
> +             init_hca->mw_enabled = 0;
>               if (dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW ||
>                   dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN)
> -                     init_hca.mw_enabled = INIT_HCA_TPT_MW_ENABLE;
> +                     init_hca->mw_enabled = INIT_HCA_TPT_MW_ENABLE;
>  
> -             err = mlx4_init_icm(dev, &dev_cap, &init_hca,
> icm_size);
> +             err = mlx4_init_icm(dev, dev_cap, init_hca, icm_size);
>               if (err)
> -                     return err;
> +                     goto out_free;
>  
> -             err = mlx4_INIT_HCA(dev, &init_hca);
> +             err = mlx4_INIT_HCA(dev, init_hca);
>               if (err) {
>                       mlx4_err(dev, "INIT_HCA command failed,
> aborting\n");
>                       goto err_free_icm;
>               }
>  
> -             if (dev_cap.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) {
> -                     err = mlx4_query_func(dev, &dev_cap);
> +             if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) {
> +                     err = mlx4_query_func(dev, dev_cap);
>                       if (err < 0) {
>                               mlx4_err(dev, "QUERY_FUNC command
> failed, aborting.\n");
>                               goto err_close;
>                       } else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) {
> -                             dev->caps.num_eqs = dev_cap.max_eqs;
> -                             dev->caps.reserved_eqs =
> dev_cap.reserved_eqs;
> -                             dev->caps.reserved_uars =
> dev_cap.reserved_uars;
> +                             dev->caps.num_eqs = dev_cap->max_eqs;
> +                             dev->caps.reserved_eqs = dev_cap-
> >reserved_eqs;
> +                             dev->caps.reserved_uars = dev_cap-
> >reserved_uars;
>                       }
>               }
>  
> @@ -2381,14 +2389,13 @@ static int mlx4_init_hca(struct mlx4_dev
> *dev)
>                * read HCA frequency by QUERY_HCA command
>                */
>               if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS) {
> -                     memset(&init_hca, 0, sizeof(init_hca));
> -                     err = mlx4_QUERY_HCA(dev, &init_hca);
> +                     err = mlx4_QUERY_HCA(dev, init_hca);
>                       if (err) {
>                               mlx4_err(dev, "QUERY_HCA command
> failed, disable timestamp\n");
>                               dev->caps.flags2 &=
> ~MLX4_DEV_CAP_FLAG2_TS;
>                       } else {
>                               dev->caps.hca_core_clock =
> -                                     init_hca.hca_core_clock;
> +                                     init_hca->hca_core_clock;
>                       }
>  
>                       /* In case we got HCA frequency 0 - disable
> timestamping
> @@ -2464,7 +2471,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
>       priv->eq_table.inta_pin = adapter.inta_pin;
>       memcpy(dev->board_id, adapter.board_id, sizeof(dev->board_id));
>  
> -     return 0;
> +     err = 0;
> +     goto out_free;
>  
>  unmap_bf:
>       unmap_internal_clock(dev);
> @@ -2483,6 +2491,10 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
>       if (!mlx4_is_slave(dev))
>               mlx4_free_icms(dev);
>  
> +out_free:
> +     kfree(dev_cap);
> +     kfree(init_hca);
> +
>       return err;
>  }
>  

Reply via email to