net/mlx5: optimize flow counter handle type
authorSuanming Mou <suanmingm@mellanox.com>
Tue, 7 Apr 2020 03:59:45 +0000 (11:59 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 21 Apr 2020 11:57:07 +0000 (13:57 +0200)
Currently, DV and verbs counters are both changed to indexed. It means
while creating the flow with counter, flow can save the indexed value to
address the counter.

Save the 4 bytes indexed value in the rte_flow instead of 8 bytes
pointer helps to save memory with millions of flows.

Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
Acked-by: Matan Azrad <matan@mellanox.com>
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_flow.c
drivers/net/mlx5/mlx5_flow.h
drivers/net/mlx5/mlx5_flow_dv.c
drivers/net/mlx5/mlx5_flow_verbs.c

index a6cd2b3..302566c 100644 (file)
@@ -764,9 +764,9 @@ void mlx5_flow_async_pool_query_handle(struct mlx5_ibv_shared *sh,
                                       uint64_t async_id, int status);
 void mlx5_set_query_alarm(struct mlx5_ibv_shared *sh);
 void mlx5_flow_query_alarm(void *arg);
-struct mlx5_flow_counter *mlx5_counter_alloc(struct rte_eth_dev *dev);
-void mlx5_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt);
-int mlx5_counter_query(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt,
+uint32_t mlx5_counter_alloc(struct rte_eth_dev *dev);
+void mlx5_counter_free(struct rte_eth_dev *dev, uint32_t cnt);
+int mlx5_counter_query(struct rte_eth_dev *dev, uint32_t cnt,
                       bool clear, uint64_t *pkts, uint64_t *bytes);
 int mlx5_flow_dev_dump(struct rte_eth_dev *dev, FILE *file,
                       struct rte_flow_error *error);
index d2e9cc4..3b358b6 100644 (file)
@@ -5494,9 +5494,9 @@ mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev,
  *   Pointer to Ethernet device structure.
  *
  * @return
- *   Pointer to allocated counter  on success, NULL otherwise.
+ *   Index to allocated counter  on success, 0 otherwise.
  */
-struct mlx5_flow_counter *
+uint32_t
 mlx5_counter_alloc(struct rte_eth_dev *dev)
 {
        const struct mlx5_flow_driver_ops *fops;
@@ -5509,7 +5509,7 @@ mlx5_counter_alloc(struct rte_eth_dev *dev)
        DRV_LOG(ERR,
                "port %u counter allocate is not supported.",
                 dev->data->port_id);
-       return NULL;
+       return 0;
 }
 
 /**
@@ -5518,10 +5518,10 @@ mlx5_counter_alloc(struct rte_eth_dev *dev)
  * @param[in] dev
  *   Pointer to Ethernet device structure.
  * @param[in] cnt
- *   Pointer to counter to be free.
+ *   Index to counter to be free.
  */
 void
-mlx5_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt)
+mlx5_counter_free(struct rte_eth_dev *dev, uint32_t cnt)
 {
        const struct mlx5_flow_driver_ops *fops;
        struct rte_flow_attr attr = { .transfer = 0 };
@@ -5542,7 +5542,7 @@ mlx5_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt)
  * @param[in] dev
  *   Pointer to Ethernet device structure.
  * @param[in] cnt
- *   Pointer to counter to query.
+ *   Index to counter to query.
  * @param[in] clear
  *   Set to clear counter statistics.
  * @param[out] pkts
@@ -5554,7 +5554,7 @@ mlx5_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt)
  *   0 on success, a negative errno value otherwise.
  */
 int
-mlx5_counter_query(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt,
+mlx5_counter_query(struct rte_eth_dev *dev, uint32_t cnt,
                   bool clear, uint64_t *pkts, uint64_t *bytes)
 {
        const struct mlx5_flow_driver_ops *fops;
index 0f0e59d..daa1f84 100644 (file)
@@ -632,7 +632,7 @@ struct mlx5_flow {
 
 /* Meter policer statistics */
 struct mlx5_flow_policer_stats {
-       struct mlx5_flow_counter *cnt[RTE_COLORS + 1];
+       uint32_t cnt[RTE_COLORS + 1];
        /**< Color counter, extra for drop. */
        uint64_t stats_mask;
        /**< Statistics mask for the colors. */
@@ -729,7 +729,7 @@ struct rte_flow {
        TAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */
        enum mlx5_flow_drv_type drv_type; /**< Driver type. */
        struct mlx5_flow_rss rss; /**< RSS context. */
-       struct mlx5_flow_counter *counter; /**< Holds flow counter. */
+       uint32_t counter; /**< Holds flow counter. */
        struct mlx5_flow_mreg_copy_resource *mreg_copy;
        /**< pointer to metadata register copy table resource. */
        struct mlx5_flow_meter *meter; /**< Holds flow meter. */
@@ -780,12 +780,12 @@ typedef int (*mlx5_flow_destroy_policer_rules_t)
                                        (struct rte_eth_dev *dev,
                                         const struct mlx5_flow_meter *fm,
                                         const struct rte_flow_attr *attr);
-typedef struct mlx5_flow_counter * (*mlx5_flow_counter_alloc_t)
+typedef uint32_t (*mlx5_flow_counter_alloc_t)
                                   (struct rte_eth_dev *dev);
 typedef void (*mlx5_flow_counter_free_t)(struct rte_eth_dev *dev,
-                                        struct mlx5_flow_counter *cnt);
+                                        uint32_t cnt);
 typedef int (*mlx5_flow_counter_query_t)(struct rte_eth_dev *dev,
-                                        struct mlx5_flow_counter *cnt,
+                                        uint32_t cnt,
                                         bool clear, uint64_t *pkts,
                                         uint64_t *bytes);
 struct mlx5_flow_driver_ops {
index 955f43b..9032d50 100644 (file)
@@ -3892,7 +3892,7 @@ flow_dv_counter_alloc_fallback(struct rte_eth_dev *dev, uint32_t shared,
  * @param[in] dev
  *   Pointer to the Ethernet device structure.
  * @param[in] counter
- *   Pointer to the counter handler.
+ *   Index to the counter handler.
  */
 static void
 flow_dv_counter_release_fallback(struct rte_eth_dev *dev __rte_unused,
@@ -4384,9 +4384,9 @@ flow_dv_counter_shared_search(struct mlx5_pools_container *cont, uint32_t id,
  *   Counter flow group.
  *
  * @return
- *   pointer to flow counter on success, NULL otherwise and rte_errno is set.
+ *   Index to flow counter on success, 0 otherwise and rte_errno is set.
  */
-static struct mlx5_flow_counter *
+static uint32_t
 flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id,
                      uint16_t group)
 {
@@ -4408,24 +4408,24 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id,
 
        if (!priv->config.devx) {
                rte_errno = ENOTSUP;
-               return NULL;
+               return 0;
        }
        if (shared) {
                cnt_free = flow_dv_counter_shared_search(cont, id, &pool);
                if (cnt_free) {
                        if (cnt_free->ref_cnt + 1 == 0) {
                                rte_errno = E2BIG;
-                               return NULL;
+                               return 0;
                        }
                        cnt_free->ref_cnt++;
                        cnt_idx = pool->index * MLX5_COUNTERS_PER_POOL +
                                  (cnt_free - pool->counters_raw) + 1;
-                       return (struct mlx5_flow_counter *)(uintptr_t)cnt_idx;
+                       return cnt_idx;
                }
        }
        if (priv->counter_fallback)
-               return (struct mlx5_flow_counter *)(uintptr_t)
-                      flow_dv_counter_alloc_fallback(dev, shared, id);
+               return flow_dv_counter_alloc_fallback(dev, shared, id);
+
        /* Pools which has a free counters are in the start. */
        TAILQ_FOREACH(pool, &cont->pool_list, next) {
                /*
@@ -4446,7 +4446,7 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id,
        if (!cnt_free) {
                cont = flow_dv_counter_pool_prepare(dev, &cnt_free, batch);
                if (!cont)
-                       return NULL;
+                       return 0;
                pool = TAILQ_FIRST(&cont->pool_list);
        }
        cnt_free->batch = batch;
@@ -4466,13 +4466,13 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id,
                                        (dcs->obj, offset);
                if (!cnt_free->action) {
                        rte_errno = errno;
-                       return NULL;
+                       return 0;
                }
        }
        /* Update the counter reset values. */
        if (_flow_dv_query_count(dev, cnt_free, &cnt_free->hits,
                                 &cnt_free->bytes))
-               return NULL;
+               return 0;
        cnt_free->shared = shared;
        cnt_free->ref_cnt = 1;
        cnt_free->id = id;
@@ -4488,7 +4488,7 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id,
        cnt_idx = MLX5_MAKE_CNT_IDX(pool->index,
                                    (cnt_free - pool->counters_raw));
        cnt_idx += batch * MLX5_CNT_BATCH_OFFSET;
-       return (struct mlx5_flow_counter *)(uintptr_t)cnt_idx;
+       return cnt_idx;
 }
 
 /**
@@ -4497,11 +4497,10 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t shared, uint32_t id,
  * @param[in] dev
  *   Pointer to the Ethernet device structure.
  * @param[in] counter
- *   Pointer to the counter handler.
+ *   Index to the counter handler.
  */
 static void
-flow_dv_counter_release(struct rte_eth_dev *dev,
-                       struct mlx5_flow_counter *counter)
+flow_dv_counter_release(struct rte_eth_dev *dev, uint32_t counter)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_flow_counter_pool *pool;
@@ -4509,7 +4508,7 @@ flow_dv_counter_release(struct rte_eth_dev *dev,
 
        if (!counter)
                return;
-       cnt = flow_dv_counter_get_by_idx(dev, (uintptr_t)counter, &pool);
+       cnt = flow_dv_counter_get_by_idx(dev, counter, &pool);
        if (priv->counter_fallback) {
                flow_dv_counter_release_fallback(dev, cnt);
                return;
@@ -7588,11 +7587,11 @@ __flow_dv_translate(struct rte_eth_dev *dev,
                                                        count->shared,
                                                        count->id,
                                                        dev_flow->dv.group);
-                       if (flow->counter == NULL)
+                       if (!flow->counter)
                                goto cnt_err;
                        dev_flow->dv.actions[actions_n++] =
                                  (flow_dv_counter_get_by_idx(dev,
-                                 (uintptr_t)flow->counter, NULL))->action;
+                                 flow->counter, NULL))->action;
                        action_flags |= MLX5_FLOW_ACTION_COUNT;
                        break;
 cnt_err:
@@ -8465,7 +8464,7 @@ __flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
        __flow_dv_remove(dev, flow);
        if (flow->counter) {
                flow_dv_counter_release(dev, flow->counter);
-               flow->counter = NULL;
+               flow->counter = 0;
        }
        if (flow->meter) {
                mlx5_flow_meter_detach(flow->meter);
@@ -8524,7 +8523,7 @@ flow_dv_query_count(struct rte_eth_dev *dev, struct rte_flow *flow,
                uint64_t pkts, bytes;
                struct mlx5_flow_counter *cnt;
 
-               cnt = flow_dv_counter_get_by_idx(dev, (uintptr_t)flow->counter,
+               cnt = flow_dv_counter_get_by_idx(dev, flow->counter,
                                                 NULL);
                int err = _flow_dv_query_count(dev, cnt, &pkts,
                                               &bytes);
@@ -8793,7 +8792,7 @@ flow_dv_create_mtr_tbl(struct rte_eth_dev *dev,
                if (!fm->policer_stats.cnt[i])
                        continue;
                cnt = flow_dv_counter_get_by_idx(dev,
-                     (uintptr_t)fm->policer_stats.cnt[i], NULL);
+                     fm->policer_stats.cnt[i], NULL);
                mtb->count_actns[i] = cnt->action;
        }
        /* Create drop action. */
@@ -9013,7 +9012,7 @@ error:
  * @param[in] dev
  *   Pointer to the Ethernet device structure.
  * @param[in] cnt
- *   Pointer to the flow counter.
+ *   Index to the flow counter.
  * @param[in] clear
  *   Set to clear the counter statistics.
  * @param[out] pkts
@@ -9025,8 +9024,7 @@ error:
  *   0 on success, otherwise return -1.
  */
 static int
-flow_dv_counter_query(struct rte_eth_dev *dev,
-                     struct mlx5_flow_counter *counter, bool clear,
+flow_dv_counter_query(struct rte_eth_dev *dev, uint32_t counter, bool clear,
                      uint64_t *pkts, uint64_t *bytes)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
@@ -9037,7 +9035,7 @@ flow_dv_counter_query(struct rte_eth_dev *dev,
        if (!priv->config.devx)
                return -1;
 
-       cnt = flow_dv_counter_get_by_idx(dev, (uintptr_t)counter, NULL);
+       cnt = flow_dv_counter_get_by_idx(dev, counter, NULL);
        ret = _flow_dv_query_count(dev, cnt, &inn_pkts, &inn_bytes);
        if (ret)
                return -1;
@@ -9110,10 +9108,10 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
 /*
  * Mutex-protected thunk to lock-free flow_dv_counter_alloc().
  */
-static struct mlx5_flow_counter *
+static uint32_t
 flow_dv_counter_allocate(struct rte_eth_dev *dev)
 {
-       struct mlx5_flow_counter *cnt;
+       uint32_t cnt;
 
        flow_dv_shared_lock(dev);
        cnt = flow_dv_counter_alloc(dev, 0, 0, 1);
@@ -9125,7 +9123,7 @@ flow_dv_counter_allocate(struct rte_eth_dev *dev)
  * Mutex-protected thunk to lock-free flow_dv_counter_release().
  */
 static void
-flow_dv_counter_free(struct rte_eth_dev *dev, struct mlx5_flow_counter *cnt)
+flow_dv_counter_free(struct rte_eth_dev *dev, uint32_t cnt)
 {
        flow_dv_shared_lock(dev);
        flow_dv_counter_release(dev, cnt);
index f1489f1..576334a 100644 (file)
@@ -145,9 +145,9 @@ flow_verbs_counter_create(struct rte_eth_dev *dev,
  *   Counter identifier.
  *
  * @return
- *   A pointer to the counter, NULL otherwise and rte_errno is set.
+ *   Index to the counter, 0 otherwise and rte_errno is set.
  */
-static struct mlx5_flow_counter *
+static uint32_t
 flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
@@ -166,9 +166,7 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id)
                                cnt = &pool->counters_raw[i];
                                if (cnt->shared && cnt->id == id) {
                                        cnt->ref_cnt++;
-                                       return (struct mlx5_flow_counter *)
-                                              (uintptr_t)
-                                              MLX5_MAKE_CNT_IDX(pool_idx, i);
+                                       return MLX5_MAKE_CNT_IDX(pool_idx, i);
                                }
                        }
                }
@@ -191,7 +189,7 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id)
                                     (n_valid + MLX5_CNT_CONTAINER_RESIZE);
                        pools = rte_zmalloc(__func__, size, 0);
                        if (!pools)
-                               return NULL;
+                               return 0;
                        if (n_valid) {
                                memcpy(pools, cont->pools,
                                       sizeof(struct mlx5_flow_counter_pool *) *
@@ -205,7 +203,7 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id)
                size = sizeof(*pool) + sizeof(*cnt) * MLX5_COUNTERS_PER_POOL;
                pool = rte_calloc(__func__, 1, size, 0);
                if (!pool)
-                       return NULL;
+                       return 0;
                for (i = 0; i < MLX5_COUNTERS_PER_POOL; ++i) {
                        cnt = &pool->counters_raw[i];
                        TAILQ_INSERT_HEAD(&pool->counters, cnt, next);
@@ -225,12 +223,11 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id)
        ret = flow_verbs_counter_create(dev, cnt);
        if (!ret) {
                TAILQ_REMOVE(&pool->counters, cnt, next);
-               return (struct mlx5_flow_counter *)(uintptr_t)
-                      MLX5_MAKE_CNT_IDX(pool_idx, (cnt - pool->counters_raw));
+               return MLX5_MAKE_CNT_IDX(pool_idx, (cnt - pool->counters_raw));
        }
        /* Some error occurred in Verbs library. */
        rte_errno = -ret;
-       return NULL;
+       return 0;
 }
 
 /**
@@ -239,18 +236,17 @@ flow_verbs_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id)
  * @param[in] dev
  *   Pointer to the Ethernet device structure.
  * @param[in] counter
- *   Pointer to the counter handler.
+ *   Index to the counter handler.
  */
 static void
-flow_verbs_counter_release(struct rte_eth_dev *dev,
-                          struct mlx5_flow_counter *counter)
+flow_verbs_counter_release(struct rte_eth_dev *dev, uint32_t counter)
 {
        struct mlx5_flow_counter_pool *pool;
        struct mlx5_flow_counter *cnt;
 
-       cnt = flow_verbs_counter_get_by_idx(dev, (uintptr_t)(void *)counter,
+       cnt = flow_verbs_counter_get_by_idx(dev, counter,
                                            &pool);
-       if (--counter->ref_cnt == 0) {
+       if (--cnt->ref_cnt == 0) {
 #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42)
                claim_zero(mlx5_glue->destroy_counter_set(cnt->cs));
                cnt->cs = NULL;
@@ -275,10 +271,9 @@ flow_verbs_counter_query(struct rte_eth_dev *dev __rte_unused,
 {
 #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) || \
        defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45)
-       if (flow->counter && flow->counter->cs) {
+       if (flow->counter) {
                struct mlx5_flow_counter *cnt = flow_verbs_counter_get_by_idx
-                                               (dev, (uintptr_t)(void *)
-                                               flow->counter, NULL);
+                                               (dev, flow->counter, NULL);
                struct rte_flow_query_count *qc = data;
                uint64_t counters[2] = {0, 0};
 #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42)
@@ -1082,8 +1077,7 @@ flow_verbs_translate_action_count(struct mlx5_flow *dev_flow,
                                                  "cannot get counter"
                                                  " context.");
        }
-       cnt = flow_verbs_counter_get_by_idx(dev, (uintptr_t)(void *)
-                                           flow->counter, NULL);
+       cnt = flow_verbs_counter_get_by_idx(dev, flow->counter, NULL);
 #if defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42)
        counter.counter_set_handle = cnt->cs->handle;
        flow_verbs_spec_add(&dev_flow->verbs, &counter, size);
@@ -1775,7 +1769,7 @@ flow_verbs_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
        }
        if (flow->counter) {
                flow_verbs_counter_release(dev, flow->counter);
-               flow->counter = NULL;
+               flow->counter = 0;
        }
 }