> -----Original Message-----
> From: Matan Azrad <ma...@mellanox.com>
> Sent: Tuesday, May 12, 2020 15:52
> To: dev@dpdk.org
> Cc: Slava Ovsiienko <viachesl...@mellanox.com>; sta...@dpdk.org
> Subject: [PATCH] net/mlx5: fix counter container resize
> 
> The design of counter container resize used double buffer algorithm in order
> to synchronize between the query thread to the control thread.
> When the control thread detected resize need, it created new bigger buffer
> for the counter pools in a new container and change the container index
> atomically.
> In case the query thread had not detect the previous resize before a new one
> need was detected by the control thread, the control thread returned
> EAGAIN to the flow creation API used a COUNT action.
> 
> The rte_flow API doesn't allow unblocked commands and doesn't expect to
> get EAGAIN error type.
> 
> So, when a lot of flows were created between 2 different periodic queries, 2
> different resizes might try to be created and caused EAGAIN error.
> This behavior may blame flow creations.
> 
> Change the synchronization way to use lock instead of double buffer
> algorithm.
> 
> The critical section of this lock is very small, so flow insertion rate 
> should not
> be decreased.
> 
> Fixes: ebbac312e448 ("net/mlx5: resize a full counter container")
> Cc: sta...@dpdk.org
Acked-by: Viacheslav Ovsiienko <viachesl...@mellanox.com>

> 
> Signed-off-by: Matan Azrad <ma...@mellanox.com>
> ---
>  drivers/net/mlx5/mlx5.c            |  70 +++++++++++------------
>  drivers/net/mlx5/mlx5.h            |  23 +++++---
>  drivers/net/mlx5/mlx5_flow.c       |  37 ++++---------
>  drivers/net/mlx5/mlx5_flow.h       |   6 --
>  drivers/net/mlx5/mlx5_flow_dv.c    | 110 +++++++++++++++--------------------
> --
>  drivers/net/mlx5/mlx5_flow_verbs.c |   6 +-
>  6 files changed, 104 insertions(+), 148 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> 4f704cb..1445809 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -467,13 +467,13 @@ struct mlx5_flow_id_pool *  static void
> mlx5_flow_counters_mng_init(struct mlx5_ibv_shared *sh)  {
> -     uint8_t i, age;
> +     int i;
> 
> -     sh->cmng.age = 0;
> +     memset(&sh->cmng, 0, sizeof(sh->cmng));
>       TAILQ_INIT(&sh->cmng.flow_counters);
> -     for (age = 0; age < RTE_DIM(sh->cmng.ccont[0]); ++age) {
> -             for (i = 0; i < RTE_DIM(sh->cmng.ccont); ++i)
> -                     TAILQ_INIT(&sh->cmng.ccont[i][age].pool_list);
> +     for (i = 0; i < MLX5_CCONT_TYPE_MAX; ++i) {
> +             TAILQ_INIT(&sh->cmng.ccont[i].pool_list);
> +             rte_spinlock_init(&sh->cmng.ccont[i].resize_sl);
>       }
>  }
> 
> @@ -504,7 +504,7 @@ struct mlx5_flow_id_pool *
> mlx5_flow_counters_mng_close(struct mlx5_ibv_shared *sh)  {
>       struct mlx5_counter_stats_mem_mng *mng;
> -     uint8_t i, age = 0;
> +     int i;
>       int j;
>       int retries = 1024;
> 
> @@ -515,42 +515,34 @@ struct mlx5_flow_id_pool *
>                       break;
>               rte_pause();
>       }
> +     for (i = 0; i < MLX5_CCONT_TYPE_MAX; ++i) {
> +             struct mlx5_flow_counter_pool *pool;
> +             uint32_t batch = !!(i > 1);
> 
> -     for (age = 0; age < RTE_DIM(sh->cmng.ccont[0]); ++age) {
> -             for (i = 0; i < RTE_DIM(sh->cmng.ccont); ++i) {
> -                     struct mlx5_flow_counter_pool *pool;
> -                     uint32_t batch = !!(i % 2);
> -
> -                     if (!sh->cmng.ccont[i][age].pools)
> -                             continue;
> -                     pool = TAILQ_FIRST(&sh-
> >cmng.ccont[i][age].pool_list);
> -                     while (pool) {
> -                             if (batch) {
> -                                     if (pool->min_dcs)
> -                                             claim_zero
> -                                             (mlx5_devx_cmd_destroy
> -                                             (pool->min_dcs));
> -                             }
> -                             for (j = 0; j < MLX5_COUNTERS_PER_POOL;
> ++j) {
> -                                     if (MLX5_POOL_GET_CNT(pool, j)-
> >action)
> -                                             claim_zero
> -                                             (mlx5_glue-
> >destroy_flow_action
> -                                              (MLX5_POOL_GET_CNT
> -                                               (pool, j)->action));
> -                                     if (!batch &&
> MLX5_GET_POOL_CNT_EXT
> -                                         (pool, j)->dcs)
> -
>       claim_zero(mlx5_devx_cmd_destroy
> -
> (MLX5_GET_POOL_CNT_EXT
> -                                                       (pool, j)->dcs));
> -                             }
> -                             TAILQ_REMOVE(&sh-
> >cmng.ccont[i][age].pool_list,
> -                                     pool, next);
> -                             rte_free(pool);
> -                             pool = TAILQ_FIRST
> -                                     (&sh->cmng.ccont[i][age].pool_list);
> +             if (!sh->cmng.ccont[i].pools)
> +                     continue;
> +             pool = TAILQ_FIRST(&sh->cmng.ccont[i].pool_list);
> +             while (pool) {
> +                     if (batch && pool->min_dcs)
> +                             claim_zero(mlx5_devx_cmd_destroy
> +                                                            (pool->min_dcs));
> +                     for (j = 0; j < MLX5_COUNTERS_PER_POOL; ++j) {
> +                             if (MLX5_POOL_GET_CNT(pool, j)->action)
> +                                     claim_zero
> +                                      (mlx5_glue->destroy_flow_action
> +                                       (MLX5_POOL_GET_CNT
> +                                       (pool, j)->action));
> +                             if (!batch && MLX5_GET_POOL_CNT_EXT
> +                                 (pool, j)->dcs)
> +                                     claim_zero(mlx5_devx_cmd_destroy
> +
> (MLX5_GET_POOL_CNT_EXT
> +                                                 (pool, j)->dcs));
>                       }
> -                     rte_free(sh->cmng.ccont[i][age].pools);
> +                     TAILQ_REMOVE(&sh->cmng.ccont[i].pool_list, pool,
> next);
> +                     rte_free(pool);
> +                     pool = TAILQ_FIRST(&sh->cmng.ccont[i].pool_list);
>               }
> +             rte_free(sh->cmng.ccont[i].pools);
>       }
>       mng = LIST_FIRST(&sh->cmng.mem_mngs);
>       while (mng) {
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index
> 1740d4a..d9f5d81 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -227,13 +227,11 @@ struct mlx5_drop {  #define CNTEXT_SIZE
> (sizeof(struct mlx5_flow_counter_ext))  #define AGE_SIZE (sizeof(struct
> mlx5_age_param))
>  #define MLX5_AGING_TIME_DELAY        7
> -
>  #define CNT_POOL_TYPE_EXT    (1 << 0)
>  #define CNT_POOL_TYPE_AGE    (1 << 1)
>  #define IS_EXT_POOL(pool) (((pool)->type) & CNT_POOL_TYPE_EXT)
> #define IS_AGE_POOL(pool) (((pool)->type) & CNT_POOL_TYPE_AGE)
> #define MLX_CNT_IS_AGE(counter) ((counter) & MLX5_CNT_AGE_OFFSET ? 1
> : 0)
> -
>  #define MLX5_CNT_LEN(pool) \
>       (CNT_SIZE + \
>       (IS_AGE_POOL(pool) ? AGE_SIZE : 0) + \ @@ -270,6 +268,17 @@
> enum {
>       AGE_TMOUT, /* Timeout, wait for rte_flow_get_aged_flows and
> destroy. */  };
> 
> +#define MLX5_CNT_CONTAINER(sh, batch, age) (&(sh)->cmng.ccont \
> +                                         [(batch) * 2 + (age)])
> +
> +enum {
> +     MLX5_CCONT_TYPE_SINGLE,
> +     MLX5_CCONT_TYPE_SINGLE_FOR_AGE,
> +     MLX5_CCONT_TYPE_BATCH,
> +     MLX5_CCONT_TYPE_BATCH_FOR_AGE,
> +     MLX5_CCONT_TYPE_MAX,
> +};
> +
>  /* Counter age parameter. */
>  struct mlx5_age_param {
>       rte_atomic16_t state; /**< Age state. */ @@ -313,7 +322,6 @@
> struct mlx5_flow_counter_ext {
>       };
>  };
> 
> -
>  TAILQ_HEAD(mlx5_counters, mlx5_flow_counter);
> 
>  /* Generic counter pool structure - query is in pool resolution. */ @@ -
> 358,17 +366,16 @@ struct mlx5_counter_stats_raw {  struct
> mlx5_pools_container {
>       rte_atomic16_t n_valid; /* Number of valid pools. */
>       uint16_t n; /* Number of pools. */
> +     rte_spinlock_t resize_sl; /* The resize lock. */
>       struct mlx5_counter_pools pool_list; /* Counter pool list. */
>       struct mlx5_flow_counter_pool **pools; /* Counter pool array. */
> -     struct mlx5_counter_stats_mem_mng *init_mem_mng;
> +     struct mlx5_counter_stats_mem_mng *mem_mng;
>       /* Hold the memory management for the next allocated pools raws.
> */  };
> 
>  /* Counter global management structure. */  struct
> mlx5_flow_counter_mng {
> -     uint8_t mhi[2][2]; /* master \ host and age \ no age container index.
> */
> -     struct mlx5_pools_container ccont[2 * 2][2];
> -     /* master \ host and age \ no age pools container. */
> +     struct mlx5_pools_container ccont[MLX5_CCONT_TYPE_MAX];
>       struct mlx5_counters flow_counters; /* Legacy flow counter list. */
>       uint8_t pending_queries;
>       uint8_t batch;
> @@ -378,6 +385,7 @@ struct mlx5_flow_counter_mng {
>       LIST_HEAD(mem_mngs, mlx5_counter_stats_mem_mng)
> mem_mngs;
>       LIST_HEAD(stat_raws, mlx5_counter_stats_raw) free_stat_raws;  };
> +
>  #define MLX5_AGE_EVENT_NEW           1
>  #define MLX5_AGE_TRIGGER             2
>  #define MLX5_AGE_SET(age_info, BIT) \
> @@ -393,6 +401,7 @@ struct mlx5_age_info {
>       struct mlx5_counters aged_counters; /* Aged flow counter list. */
>       rte_spinlock_t aged_sl; /* Aged flow counter list lock. */  };
> +
>  /* Per port data of shared IB device. */  struct mlx5_ibv_shared_port {
>       uint32_t ih_port_id;
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index 08c7cdf..ae478a5 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -5801,16 +5801,11 @@ struct mlx5_meter_domains_infos *  static
> uint32_t  mlx5_get_all_valid_pool_count(struct mlx5_ibv_shared *sh)  {
> -     uint8_t age, i;
> +     int i;
>       uint32_t pools_n = 0;
> -     struct mlx5_pools_container *cont;
> 
> -     for (age = 0; age < RTE_DIM(sh->cmng.ccont[0]); ++age) {
> -             for (i = 0; i < 2 ; ++i) {
> -                     cont = MLX5_CNT_CONTAINER(sh, i, 0, age);
> -                     pools_n += rte_atomic16_read(&cont->n_valid);
> -             }
> -     }
> +     for (i = 0; i < MLX5_CCONT_TYPE_MAX; ++i)
> +             pools_n += rte_atomic16_read(&sh->cmng.ccont[i].n_valid);
>       return pools_n;
>  }
> 
> @@ -5855,32 +5850,19 @@ struct mlx5_meter_domains_infos *
>       uint8_t age = sh->cmng.age;
>       uint16_t pool_index = sh->cmng.pool_index;
>       struct mlx5_pools_container *cont;
> -     struct mlx5_pools_container *mcont;
>       struct mlx5_flow_counter_pool *pool;
> +     int cont_loop = MLX5_CCONT_TYPE_MAX;
> 
>       if (sh->cmng.pending_queries >= MLX5_MAX_PENDING_QUERIES)
>               goto set_alarm;
>  next_container:
> -     cont = MLX5_CNT_CONTAINER(sh, batch, 1, age);
> -     mcont = MLX5_CNT_CONTAINER(sh, batch, 0, age);
> -     /* Check if resize was done and need to flip a container. */
> -     if (cont != mcont) {
> -             if (cont->pools) {
> -                     /* Clean the old container. */
> -                     rte_free(cont->pools);
> -                     memset(cont, 0, sizeof(*cont));
> -             }
> -             rte_cio_wmb();
> -              /* Flip the host container. */
> -             sh->cmng.mhi[batch][age] ^= (uint8_t)2;
> -             cont = mcont;
> -     }
> +     cont = MLX5_CNT_CONTAINER(sh, batch, age);
> +     rte_spinlock_lock(&cont->resize_sl);
>       if (!cont->pools) {
> -             /* 2 empty containers case is unexpected. */
> -             if (unlikely(batch != sh->cmng.batch) &&
> -                     unlikely(age != sh->cmng.age)) {
> +             rte_spinlock_unlock(&cont->resize_sl);
> +             /* Check if all the containers are empty. */
> +             if (unlikely(--cont_loop == 0))
>                       goto set_alarm;
> -             }
>               batch ^= 0x1;
>               pool_index = 0;
>               if (batch == 0 && pool_index == 0) {
> @@ -5891,6 +5873,7 @@ struct mlx5_meter_domains_infos *
>               goto next_container;
>       }
>       pool = cont->pools[pool_index];
> +     rte_spinlock_unlock(&cont->resize_sl);
>       if (pool->raw_hw)
>               /* There is a pool query in progress. */
>               goto set_alarm;
> diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
> index 7f5e01f..2c96677 100644
> --- a/drivers/net/mlx5/mlx5_flow.h
> +++ b/drivers/net/mlx5/mlx5_flow.h
> @@ -900,12 +900,6 @@ struct mlx5_flow_driver_ops {
>       mlx5_flow_get_aged_flows_t get_aged_flows;  };
> 
> -
> -#define MLX5_CNT_CONTAINER(sh, batch, thread, age) (&(sh)->cmng.ccont
> \
> -     [(((sh)->cmng.mhi[batch][age] >> (thread)) & 0x1) * 2 + (batch)][age])
> -#define MLX5_CNT_CONTAINER_UNUSED(sh, batch, thread, age) (&(sh)-
> >cmng.ccont \
> -     [(~((sh)->cmng.mhi[batch][age] >> (thread)) & 0x1) * 2 +
> (batch)][age])
> -
>  /* mlx5_flow.c */
> 
>  struct mlx5_flow_id_pool *mlx5_flow_id_pool_alloc(uint32_t max_id); diff -
> -git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
> index 4ebb7ce..c46a589 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -4038,7 +4038,7 @@ struct field_modify_info modify_tcp[] = {
>               idx -= MLX5_CNT_BATCH_OFFSET;
>               batch = 1;
>       }
> -     cont = MLX5_CNT_CONTAINER(priv->sh, batch, 0, age);
> +     cont = MLX5_CNT_CONTAINER(priv->sh, batch, age);
>       MLX5_ASSERT(idx / MLX5_COUNTERS_PER_POOL < cont->n);
>       pool = cont->pools[idx / MLX5_COUNTERS_PER_POOL];
>       MLX5_ASSERT(pool);
> @@ -4162,69 +4162,55 @@ struct field_modify_info modify_tcp[] = {
>   *   Whether the pool is for Aging counter.
>   *
>   * @return
> - *   The new container pointer on success, otherwise NULL and rte_errno is
> set.
> + *   0 on success, otherwise negative errno value and rte_errno is set.
>   */
> -static struct mlx5_pools_container *
> +static int
>  flow_dv_container_resize(struct rte_eth_dev *dev,
>                               uint32_t batch, uint32_t age)
>  {
>       struct mlx5_priv *priv = dev->data->dev_private;
> -     struct mlx5_pools_container *cont =
> -                     MLX5_CNT_CONTAINER(priv->sh, batch, 0, age);
> -     struct mlx5_pools_container *new_cont =
> -                     MLX5_CNT_CONTAINER_UNUSED(priv->sh, batch, 0,
> age);
> +     struct mlx5_pools_container *cont = MLX5_CNT_CONTAINER(priv-
> >sh, batch,
> +                                                            age);
>       struct mlx5_counter_stats_mem_mng *mem_mng = NULL;
> +     void *old_pools = cont->pools;
>       uint32_t resize = cont->n + MLX5_CNT_CONTAINER_RESIZE;
>       uint32_t mem_size = sizeof(struct mlx5_flow_counter_pool *) *
> resize;
> -     int i;
> +     void *pools = rte_calloc(__func__, 1, mem_size, 0);
> 
> -     /* Fallback mode has no background thread. Skip the check. */
> -     if (!priv->counter_fallback &&
> -         cont != MLX5_CNT_CONTAINER(priv->sh, batch, 1, age)) {
> -             /* The last resize still hasn't detected by the host thread. */
> -             rte_errno = EAGAIN;
> -             return NULL;
> -     }
> -     new_cont->pools = rte_calloc(__func__, 1, mem_size, 0);
> -     if (!new_cont->pools) {
> +     if (!pools) {
>               rte_errno = ENOMEM;
> -             return NULL;
> +             return -ENOMEM;
>       }
> -     if (cont->n)
> -             memcpy(new_cont->pools, cont->pools, cont->n *
> -                    sizeof(struct mlx5_flow_counter_pool *));
> +     if (old_pools)
> +             memcpy(pools, old_pools, cont->n *
> +                                    sizeof(struct mlx5_flow_counter_pool
> *));
>       /*
>        * Fallback mode query the counter directly, no background query
>        * resources are needed.
>        */
>       if (!priv->counter_fallback) {
> +             int i;
> +
>               mem_mng = flow_dv_create_counter_stat_mem_mng(dev,
> -                     MLX5_CNT_CONTAINER_RESIZE +
> MLX5_MAX_PENDING_QUERIES);
> +                       MLX5_CNT_CONTAINER_RESIZE +
> MLX5_MAX_PENDING_QUERIES);
>               if (!mem_mng) {
> -                     rte_free(new_cont->pools);
> -                     return NULL;
> +                     rte_free(pools);
> +                     return -ENOMEM;
>               }
>               for (i = 0; i < MLX5_MAX_PENDING_QUERIES; ++i)
>                       LIST_INSERT_HEAD(&priv->sh-
> >cmng.free_stat_raws,
>                                        mem_mng->raws +
>                                        MLX5_CNT_CONTAINER_RESIZE +
>                                        i, next);
> -     } else {
> -             /*
> -              * Release the old container pools directly as no background
> -              * thread helps that.
> -              */
> -             rte_free(cont->pools);
>       }
> -     new_cont->n = resize;
> -     rte_atomic16_set(&new_cont->n_valid, rte_atomic16_read(&cont-
> >n_valid));
> -     TAILQ_INIT(&new_cont->pool_list);
> -     TAILQ_CONCAT(&new_cont->pool_list, &cont->pool_list, next);
> -     new_cont->init_mem_mng = mem_mng;
> -     rte_cio_wmb();
> -      /* Flip the master container. */
> -     priv->sh->cmng.mhi[batch][age] ^= (uint8_t)1;
> -     return new_cont;
> +     rte_spinlock_lock(&cont->resize_sl);
> +     cont->n = resize;
> +     cont->mem_mng = mem_mng;
> +     cont->pools = pools;
> +     rte_spinlock_unlock(&cont->resize_sl);
> +     if (old_pools)
> +             rte_free(old_pools);
> +     return 0;
>  }
> 
>  /**
> @@ -4296,22 +4282,19 @@ struct field_modify_info modify_tcp[] = {
>   * @return
>   *   The pool container pointer on success, NULL otherwise and rte_errno is
> set.
>   */
> -static struct mlx5_pools_container *
> +static struct mlx5_flow_counter_pool *
>  flow_dv_pool_create(struct rte_eth_dev *dev, struct mlx5_devx_obj *dcs,
>                   uint32_t batch, uint32_t age)
>  {
>       struct mlx5_priv *priv = dev->data->dev_private;
>       struct mlx5_flow_counter_pool *pool;
>       struct mlx5_pools_container *cont = MLX5_CNT_CONTAINER(priv-
> >sh, batch,
> -                                                            0, age);
> +                                                            age);
>       int16_t n_valid = rte_atomic16_read(&cont->n_valid);
>       uint32_t size = sizeof(*pool);
> 
> -     if (cont->n == n_valid) {
> -             cont = flow_dv_container_resize(dev, batch, age);
> -             if (!cont)
> -                     return NULL;
> -     }
> +     if (cont->n == n_valid && flow_dv_container_resize(dev, batch, age))
> +             return NULL;
>       size += MLX5_COUNTERS_PER_POOL * CNT_SIZE;
>       size += (batch ? 0 : MLX5_COUNTERS_PER_POOL * CNTEXT_SIZE);
>       size += (!age ? 0 : MLX5_COUNTERS_PER_POOL * AGE_SIZE); @@ -
> 4322,8 +4305,8 @@ struct field_modify_info modify_tcp[] = {
>       }
>       pool->min_dcs = dcs;
>       if (!priv->counter_fallback)
> -             pool->raw = cont->init_mem_mng->raws + n_valid %
> -
> MLX5_CNT_CONTAINER_RESIZE;
> +             pool->raw = cont->mem_mng->raws + n_valid %
> +
> MLX5_CNT_CONTAINER_RESIZE;
>       pool->raw_hw = NULL;
>       pool->type = 0;
>       pool->type |= (batch ? 0 :  CNT_POOL_TYPE_EXT); @@ -4351,7
> +4334,7 @@ struct field_modify_info modify_tcp[] = {
>       /* Pool initialization must be updated before host thread access. */
>       rte_cio_wmb();
>       rte_atomic16_add(&cont->n_valid, 1);
> -     return cont;
> +     return pool;
>  }
> 
>  /**
> @@ -4375,7 +4358,7 @@ struct field_modify_info modify_tcp[] = {
>       struct mlx5_flow_counter_pool *other;
>       struct mlx5_pools_container *cont;
> 
> -     cont = MLX5_CNT_CONTAINER(priv->sh, batch, 0, (age ^ 0x1));
> +     cont = MLX5_CNT_CONTAINER(priv->sh, batch, (age ^ 0x1));
>       other = flow_dv_find_pool_by_id(cont, pool->min_dcs->id);
>       if (!other)
>               return;
> @@ -4400,10 +4383,10 @@ struct field_modify_info modify_tcp[] = {
>   *   Whether the pool is for counter that was allocated for aging.
>   *
>   * @return
> - *   The counter container pointer and @p cnt_free is set on success,
> + *   The counter pool pointer and @p cnt_free is set on success,
>   *   NULL otherwise and rte_errno is set.
>   */
> -static struct mlx5_pools_container *
> +static struct mlx5_flow_counter_pool *
>  flow_dv_counter_pool_prepare(struct rte_eth_dev *dev,
>                            struct mlx5_flow_counter **cnt_free,
>                            uint32_t batch, uint32_t age)
> @@ -4415,7 +4398,7 @@ struct field_modify_info modify_tcp[] = {
>       struct mlx5_flow_counter *cnt;
>       uint32_t i;
> 
> -     cont = MLX5_CNT_CONTAINER(priv->sh, batch, 0, age);
> +     cont = MLX5_CNT_CONTAINER(priv->sh, batch, age);
>       if (!batch) {
>               /* bulk_bitmap must be 0 for single counter allocation. */
>               dcs = mlx5_devx_cmd_flow_counter_alloc(priv->sh->ctx, 0);
> @@ -4423,12 +4406,11 @@ struct field_modify_info modify_tcp[] = {
>                       return NULL;
>               pool = flow_dv_find_pool_by_id(cont, dcs->id);
>               if (!pool) {
> -                     cont = flow_dv_pool_create(dev, dcs, batch, age);
> -                     if (!cont) {
> +                     pool = flow_dv_pool_create(dev, dcs, batch, age);
> +                     if (!pool) {
>                               mlx5_devx_cmd_destroy(dcs);
>                               return NULL;
>                       }
> -                     pool = TAILQ_FIRST(&cont->pool_list);
>               } else if (dcs->id < pool->min_dcs->id) {
>                       rte_atomic64_set(&pool->a64_dcs,
>                                        (int64_t)(uintptr_t)dcs);
> @@ -4440,7 +4422,7 @@ struct field_modify_info modify_tcp[] = {
>               TAILQ_INSERT_HEAD(&pool->counters, cnt, next);
>               MLX5_GET_POOL_CNT_EXT(pool, i)->dcs = dcs;
>               *cnt_free = cnt;
> -             return cont;
> +             return pool;
>       }
>       /* bulk_bitmap is in 128 counters units. */
>       if (priv->config.hca_attr.flow_counter_bulk_alloc_bitmap & 0x4)
> @@ -4449,18 +4431,17 @@ struct field_modify_info modify_tcp[] = {
>               rte_errno = ENODATA;
>               return NULL;
>       }
> -     cont = flow_dv_pool_create(dev, dcs, batch, age);
> -     if (!cont) {
> +     pool = flow_dv_pool_create(dev, dcs, batch, age);
> +     if (!pool) {
>               mlx5_devx_cmd_destroy(dcs);
>               return NULL;
>       }
> -     pool = TAILQ_FIRST(&cont->pool_list);
>       for (i = 0; i < MLX5_COUNTERS_PER_POOL; ++i) {
>               cnt = MLX5_POOL_GET_CNT(pool, i);
>               TAILQ_INSERT_HEAD(&pool->counters, cnt, next);
>       }
>       *cnt_free = MLX5_POOL_GET_CNT(pool, 0);
> -     return cont;
> +     return pool;
>  }
> 
>  /**
> @@ -4534,7 +4515,7 @@ struct field_modify_info modify_tcp[] = {
>        */
>       uint32_t batch = (group && !shared && !priv->counter_fallback) ? 1 :
> 0;
>       struct mlx5_pools_container *cont = MLX5_CNT_CONTAINER(priv-
> >sh, batch,
> -                                                            0, age);
> +                                                            age);
>       uint32_t cnt_idx;
> 
>       if (!priv->config.devx) {
> @@ -4573,10 +4554,9 @@ struct field_modify_info modify_tcp[] = {
>               cnt_free = NULL;
>       }
>       if (!cnt_free) {
> -             cont = flow_dv_counter_pool_prepare(dev, &cnt_free,
> batch, age);
> -             if (!cont)
> +             pool = flow_dv_counter_pool_prepare(dev, &cnt_free,
> batch, age);
> +             if (!pool)
>                       return 0;
> -             pool = TAILQ_FIRST(&cont->pool_list);
>       }
>       if (!batch)
>               cnt_ext = MLX5_CNT_TO_CNT_EXT(pool, cnt_free); diff --git
> a/drivers/net/mlx5/mlx5_flow_verbs.c
> b/drivers/net/mlx5/mlx5_flow_verbs.c
> index c403f72..01eec31 100644
> --- a/drivers/net/mlx5/mlx5_flow_verbs.c
> +++ b/drivers/net/mlx5/mlx5_flow_verbs.c
> @@ -56,8 +56,7 @@
>                             struct mlx5_flow_counter_pool **ppool)  {
>       struct mlx5_priv *priv = dev->data->dev_private;
> -     struct mlx5_pools_container *cont = MLX5_CNT_CONTAINER(priv-
> >sh, 0, 0,
> -                                                                     0);
> +     struct mlx5_pools_container *cont = MLX5_CNT_CONTAINER(priv-
> >sh, 0,
> +0);
>       struct mlx5_flow_counter_pool *pool;
> 
>       idx--;
> @@ -152,8 +151,7 @@
>  flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t
> id)  {
>       struct mlx5_priv *priv = dev->data->dev_private;
> -     struct mlx5_pools_container *cont = MLX5_CNT_CONTAINER(priv-
> >sh, 0, 0,
> -                                                                     0);
> +     struct mlx5_pools_container *cont = MLX5_CNT_CONTAINER(priv-
> >sh, 0,
> +0);
>       struct mlx5_flow_counter_pool *pool = NULL;
>       struct mlx5_flow_counter_ext *cnt_ext = NULL;
>       struct mlx5_flow_counter *cnt = NULL;
> --
> 1.8.3.1

Reply via email to