net/mlx5: prepare sub-policy for flow with meter
[dpdk.git] / drivers / net / mlx5 / mlx5.c
index 99a15af..19ffa16 100644 (file)
@@ -35,6 +35,8 @@
 #include "mlx5.h"
 #include "mlx5_utils.h"
 #include "mlx5_rxtx.h"
+#include "mlx5_rx.h"
+#include "mlx5_tx.h"
 #include "mlx5_autoconf.h"
 #include "mlx5_mr.h"
 #include "mlx5_flow.h"
@@ -275,10 +277,13 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = {
        },
 #endif
        [MLX5_IPOOL_MTR] = {
-               .size = sizeof(struct mlx5_flow_meter),
+               /**
+                * The ipool index should grow continually from small to big,
+                * for meter idx, so not set grow_trunk to avoid meter index
+                * not jump continually.
+                */
+               .size = sizeof(struct mlx5_legacy_flow_meter),
                .trunk_size = 64,
-               .grow_trunk = 3,
-               .grow_shift = 2,
                .need_lock = 1,
                .release_mem_en = 1,
                .malloc = mlx5_malloc,
@@ -347,6 +352,20 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = {
                .free = mlx5_free,
                .type = "mlx5_shared_action_rss",
        },
+       [MLX5_IPOOL_MTR_POLICY] = {
+               /**
+                * The ipool index should grow continually from small to big,
+                * for policy idx, so not set grow_trunk to avoid policy index
+                * not jump continually.
+                */
+               .size = sizeof(struct mlx5_flow_meter_sub_policy),
+               .trunk_size = 64,
+               .need_lock = 1,
+               .release_mem_en = 1,
+               .malloc = mlx5_malloc,
+               .free = mlx5_free,
+               .type = "mlx5_meter_policy_ipool",
+       },
 };
 
 
@@ -398,7 +417,7 @@ mlx5_flow_aso_age_mng_init(struct mlx5_dev_ctx_shared *sh)
                rte_errno = ENOMEM;
                return -ENOMEM;
        }
-       err = mlx5_aso_queue_init(sh);
+       err = mlx5_aso_queue_init(sh, ASO_OPC_MOD_FLOW_HIT);
        if (err) {
                mlx5_free(sh->aso_age_mng);
                return -1;
@@ -420,8 +439,8 @@ mlx5_flow_aso_age_mng_close(struct mlx5_dev_ctx_shared *sh)
 {
        int i, j;
 
-       mlx5_aso_queue_stop(sh);
-       mlx5_aso_queue_uninit(sh);
+       mlx5_aso_flow_hit_queue_poll_stop(sh);
+       mlx5_aso_queue_uninit(sh, ASO_OPC_MOD_FLOW_HIT);
        if (sh->aso_age_mng->pools) {
                struct mlx5_aso_age_pool *pool;
 
@@ -559,6 +578,79 @@ mlx5_flow_counters_mng_close(struct mlx5_dev_ctx_shared *sh)
        memset(&sh->cmng, 0, sizeof(sh->cmng));
 }
 
+/**
+ * Initialize the aso flow meters management structure.
+ *
+ * @param[in] sh
+ *   Pointer to mlx5_dev_ctx_shared object to free
+ */
+int
+mlx5_aso_flow_mtrs_mng_init(struct mlx5_dev_ctx_shared *sh)
+{
+       if (!sh->mtrmng) {
+               sh->mtrmng = mlx5_malloc(MLX5_MEM_ZERO,
+                       sizeof(*sh->mtrmng),
+                       RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
+               if (!sh->mtrmng) {
+                       DRV_LOG(ERR,
+                       "meter management allocation was failed.");
+                       rte_errno = ENOMEM;
+                       return -ENOMEM;
+               }
+               if (sh->meter_aso_en) {
+                       rte_spinlock_init(&sh->mtrmng->pools_mng.mtrsl);
+                       LIST_INIT(&sh->mtrmng->pools_mng.meters);
+                       sh->mtrmng->policy_idx_tbl =
+                               mlx5_l3t_create(MLX5_L3T_TYPE_DWORD);
+               }
+               sh->mtrmng->def_policy_id = MLX5_INVALID_POLICY_ID;
+       }
+       return 0;
+}
+
+/**
+ * Close and release all the resources of
+ * the ASO flow meter management structure.
+ *
+ * @param[in] sh
+ *   Pointer to mlx5_dev_ctx_shared object to free.
+ */
+static void
+mlx5_aso_flow_mtrs_mng_close(struct mlx5_dev_ctx_shared *sh)
+{
+       struct mlx5_aso_mtr_pool *mtr_pool;
+       struct mlx5_flow_mtr_mng *mtrmng = sh->mtrmng;
+       uint32_t idx;
+#ifdef HAVE_MLX5_DR_CREATE_ACTION_ASO
+       struct mlx5_aso_mtr *aso_mtr;
+       int i;
+#endif /* HAVE_MLX5_DR_CREATE_ACTION_ASO */
+
+       if (sh->meter_aso_en) {
+               mlx5_aso_queue_uninit(sh, ASO_OPC_MOD_POLICER);
+               idx = mtrmng->pools_mng.n_valid;
+               while (idx--) {
+                       mtr_pool = mtrmng->pools_mng.pools[idx];
+#ifdef HAVE_MLX5_DR_CREATE_ACTION_ASO
+                       for (i = 0; i < MLX5_ASO_MTRS_PER_POOL; i++) {
+                               aso_mtr = &mtr_pool->mtrs[i];
+                               if (aso_mtr->fm.meter_action)
+                                       claim_zero
+                                       (mlx5_glue->destroy_flow_action
+                                       (aso_mtr->fm.meter_action));
+                       }
+#endif /* HAVE_MLX5_DR_CREATE_ACTION_ASO */
+                       claim_zero(mlx5_devx_cmd_destroy
+                                               (mtr_pool->devx_obj));
+                       mtrmng->pools_mng.n_valid--;
+                       mlx5_free(mtr_pool);
+               }
+               mlx5_free(sh->mtrmng->pools_mng.pools);
+       }
+       mlx5_free(sh->mtrmng);
+       sh->mtrmng = NULL;
+}
+
 /* Send FLOW_AGED event if needed. */
 void
 mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh)
@@ -925,6 +1017,8 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
                rte_errno  = ENOMEM;
                goto exit;
        }
+       if (spawn->bond_info)
+               sh->bond = *spawn->bond_info;
        err = mlx5_os_open_device(spawn, config, sh);
        if (!sh->ctx)
                goto error;
@@ -1106,6 +1200,8 @@ mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh)
                mlx5_flow_aso_age_mng_close(sh);
                sh->aso_age_mng = NULL;
        }
+       if (sh->mtrmng)
+               mlx5_aso_flow_mtrs_mng_close(sh);
        mlx5_flow_ipool_destroy(sh);
        mlx5_os_dev_shared_handler_uninstall(sh);
        if (sh->cnt_id_tbl) {
@@ -1190,9 +1286,12 @@ mlx5_alloc_table_hash_list(struct mlx5_priv *priv __rte_unused)
         * because DV expect to see them even if they cannot be created by
         * RDMA-CORE.
         */
-       if (!flow_dv_tbl_resource_get(dev, 0, 0, 0, 0, NULL, 0, 1, &error) ||
-           !flow_dv_tbl_resource_get(dev, 0, 1, 0, 0, NULL, 0, 1, &error) ||
-           !flow_dv_tbl_resource_get(dev, 0, 0, 1, 0, NULL, 0, 1, &error)) {
+       if (!flow_dv_tbl_resource_get(dev, 0, 0, 0, 0,
+               NULL, 0, 1, 0, &error) ||
+           !flow_dv_tbl_resource_get(dev, 0, 1, 0, 0,
+               NULL, 0, 1, 0, &error) ||
+           !flow_dv_tbl_resource_get(dev, 0, 0, 1, 0,
+               NULL, 0, 1, 0, &error)) {
                err = ENOMEM;
                goto error;
        }
@@ -1337,7 +1436,7 @@ mlx5_dev_close(struct rte_eth_dev *dev)
         * then this will return directly without any action.
         */
        mlx5_flow_list_flush(dev, &priv->flows, true);
-       mlx5_shared_action_flush(dev);
+       mlx5_action_handle_flush(dev);
        mlx5_flow_meter_flush(dev, NULL);
        /* Prevent crashes when queues are still in use. */
        dev->rx_pkt_burst = removed_rx_burst;
@@ -2114,7 +2213,7 @@ mlx5_eth_find_next(uint16_t port_id, struct rte_pci_device *pci_dev)
                    (dev->device == &pci_dev->device ||
                     (dev->device->driver &&
                     dev->device->driver->name &&
-                    !strcmp(dev->device->driver->name, MLX5_DRIVER_NAME))))
+                    !strcmp(dev->device->driver->name, MLX5_PCI_DRIVER_NAME))))
                        break;
                port_id++;
        }
@@ -2235,7 +2334,7 @@ static struct mlx5_pci_driver mlx5_driver = {
        .driver_class = MLX5_CLASS_NET,
        .pci_driver = {
                .driver = {
-                       .name = MLX5_DRIVER_NAME,
+                       .name = MLX5_PCI_DRIVER_NAME,
                },
                .id_table = mlx5_pci_id_map,
                .probe = mlx5_os_pci_probe,