return (ix + port_aff_bias) % mlx5e_get_num_lag_ports(mdev);
}
+static int mlx5e_channel_stats_alloc(struct mlx5e_priv *priv, int ix, int cpu)
+{
+ if (ix > priv->stats_nch) {
+ netdev_warn(priv->netdev, "Unexpected channel stats index %d > %d\n", ix,
+ priv->stats_nch);
+ return -EINVAL;
+ }
+
+ if (priv->channel_stats[ix])
+ return 0;
+
+ /* Asymmetric dynamic memory allocation.
+ * Freed in mlx5e_priv_arrays_free, not on channel closure.
+ */
+ mlx5e_dbg(DRV, priv, "Creating channel stats %d\n", ix);
+ priv->channel_stats[ix] = kvzalloc_node(sizeof(**priv->channel_stats),
+ GFP_KERNEL, cpu_to_node(cpu));
+ if (!priv->channel_stats[ix])
+ return -ENOMEM;
+ priv->stats_nch++;
+
+ return 0;
+}
+
static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
struct mlx5e_params *params,
struct mlx5e_channel_param *cparam,
if (err)
return err;
+ err = mlx5e_channel_stats_alloc(priv, ix, cpu);
+ if (err)
+ return err;
+
c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu));
if (!c)
return -ENOMEM;
priv->netdev = netdev;
priv->msglevel = MLX5E_MSG_LEVEL;
priv->max_nch = nch;
- priv->stats_nch = nch;
priv->max_opened_tc = 1;
if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL))
if (!priv->channel_stats)
goto err_free_channel_tc2realtxq;
- for (i = 0; i < priv->stats_nch; i++) {
- priv->channel_stats[i] = kvzalloc_node(sizeof(**priv->channel_stats),
- GFP_KERNEL, node);
- if (!priv->channel_stats[i])
- goto err_free_channel_stats;
- }
-
return 0;
-err_free_channel_stats:
- while (--i >= 0)
- kvfree(priv->channel_stats[i]);
- kfree(priv->channel_stats);
- i = nch;
err_free_channel_tc2realtxq:
while (--i >= 0)
kfree(priv->channel_tc2realtxq[i]);