/* Decap will be used or not. */
#define MLX5_DECAP_EN "decap_en"
+/* Device parameter to configure allow or prevent duplicate rules pattern. */
+#define MLX5_ALLOW_DUPLICATE_PATTERN "allow_duplicate_pattern"
+
/* Shared memory between primary and secondary processes. */
struct mlx5_shared_data *mlx5_shared_data;
.grow_trunk = 3,
.grow_shift = 2,
.need_lock = 1,
- .release_mem_en = 1,
+ .release_mem_en = 0,
+ .per_core_cache = (1 << 16),
.malloc = mlx5_malloc,
.free = mlx5_free,
.type = "mlx5_tag_ipool",
.grow_trunk = 3,
.grow_shift = 2,
.need_lock = 1,
- .release_mem_en = 1,
+ .release_mem_en = 0,
+ .per_core_cache = 1 << 19,
.malloc = mlx5_malloc,
.free = mlx5_free,
.type = "mlx5_flow_handle_ipool",
#define MLX5_FLOW_MIN_ID_POOL_SIZE 512
#define MLX5_ID_GENERATION_ARRAY_FACTOR 16
-#define MLX5_FLOW_TABLE_HLIST_ARRAY_SIZE 4096
+#define MLX5_FLOW_TABLE_HLIST_ARRAY_SIZE 1024
/**
* Decide whether representor ID is a HPF(host PF) port on BF2.
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;
}
}
}
+/*
+ * Initialize the ASO connection tracking structure.
+ *
+ * @param[in] sh
+ * Pointer to mlx5_dev_ctx_shared object.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_flow_aso_ct_mng_init(struct mlx5_dev_ctx_shared *sh)
+{
+ int err;
+
+ if (sh->ct_mng)
+ return 0;
+ sh->ct_mng = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*sh->ct_mng),
+ RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
+ if (!sh->ct_mng) {
+ DRV_LOG(ERR, "ASO CT management allocation failed.");
+ rte_errno = ENOMEM;
+ return -rte_errno;
+ }
+ err = mlx5_aso_queue_init(sh, ASO_OPC_MOD_CONNECTION_TRACKING);
+ if (err) {
+ mlx5_free(sh->ct_mng);
+ /* rte_errno should be extracted from the failure. */
+ rte_errno = EINVAL;
+ return -rte_errno;
+ }
+ rte_spinlock_init(&sh->ct_mng->ct_sl);
+ rte_rwlock_init(&sh->ct_mng->resize_rwl);
+ LIST_INIT(&sh->ct_mng->free_cts);
+ return 0;
+}
+
+/*
+ * Close and release all the resources of the
+ * ASO connection tracking management structure.
+ *
+ * @param[in] sh
+ * Pointer to mlx5_dev_ctx_shared object to free.
+ */
+static void
+mlx5_flow_aso_ct_mng_close(struct mlx5_dev_ctx_shared *sh)
+{
+ struct mlx5_aso_ct_pools_mng *mng = sh->ct_mng;
+ struct mlx5_aso_ct_pool *ct_pool;
+ struct mlx5_aso_ct_action *ct;
+ uint32_t idx;
+ uint32_t val;
+ uint32_t cnt;
+ int i;
+
+ mlx5_aso_queue_uninit(sh, ASO_OPC_MOD_CONNECTION_TRACKING);
+ idx = mng->next;
+ while (idx--) {
+ cnt = 0;
+ ct_pool = mng->pools[idx];
+ for (i = 0; i < MLX5_ASO_CT_ACTIONS_PER_POOL; i++) {
+ ct = &ct_pool->actions[i];
+ val = __atomic_fetch_sub(&ct->refcnt, 1,
+ __ATOMIC_RELAXED);
+ MLX5_ASSERT(val == 1);
+ if (val > 1)
+ cnt++;
+#ifdef HAVE_MLX5_DR_ACTION_ASO_CT
+ if (ct->dr_action_orig)
+ claim_zero(mlx5_glue->destroy_flow_action
+ (ct->dr_action_orig));
+ if (ct->dr_action_rply)
+ claim_zero(mlx5_glue->destroy_flow_action
+ (ct->dr_action_rply));
+#endif
+ }
+ claim_zero(mlx5_devx_cmd_destroy(ct_pool->devx_obj));
+ if (cnt) {
+ DRV_LOG(DEBUG, "%u ASO CT objects are being used in the pool %u",
+ cnt, i);
+ }
+ mlx5_free(ct_pool);
+ /* in case of failure. */
+ mng->next--;
+ }
+ mlx5_free(mng->pools);
+ mlx5_free(mng);
+ /* Management structure must be cleared to 0s during allocation. */
+ sh->ct_mng = NULL;
+}
+
/**
* Initialize the flow resources' indexed mempool.
*
MLX5_FLOW_HANDLE_VERBS_SIZE;
break;
}
- if (config->reclaim_mode)
+ if (config->reclaim_mode) {
cfg.release_mem_en = 1;
+ cfg.per_core_cache = 0;
+ } else {
+ cfg.release_mem_en = 0;
+ }
sh->ipool[i] = mlx5_ipool_create(&cfg);
}
}
+
/**
* Release the flow resources' indexed mempool.
*
for (i = 0; i < MLX5_IPOOL_MAX; ++i)
mlx5_ipool_destroy(sh->ipool[i]);
+ for (i = 0; i < MLX5_MAX_MODIFY_NUM; ++i)
+ if (sh->mdh_ipools[i])
+ mlx5_ipool_destroy(sh->mdh_ipools[i]);
}
/*
}
sh->refcnt = 1;
sh->max_port = spawn->max_port;
+ sh->reclaim_mode = config->reclaim_mode;
strncpy(sh->ibdev_name, mlx5_os_get_ctx_device_name(sh->ctx),
sizeof(sh->ibdev_name) - 1);
strncpy(sh->ibdev_path, mlx5_os_get_ctx_device_path(sh->ctx),
/* Tables are only used in DV and DR modes. */
#if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H)
struct mlx5_dev_ctx_shared *sh = priv->sh;
- char s[MLX5_HLIST_NAMESIZE];
+ char s[MLX5_NAME_SIZE];
MLX5_ASSERT(sh);
snprintf(s, sizeof(s), "%s_flow_table", priv->sh->ibdev_name);
sh->flow_tbls = mlx5_hlist_create(s, MLX5_FLOW_TABLE_HLIST_ARRAY_SIZE,
- 0, 0, flow_dv_tbl_create_cb,
+ false, true, sh,
+ flow_dv_tbl_create_cb,
flow_dv_tbl_match_cb,
- flow_dv_tbl_remove_cb);
+ flow_dv_tbl_remove_cb,
+ flow_dv_tbl_clone_cb,
+ flow_dv_tbl_clone_free_cb);
if (!sh->flow_tbls) {
DRV_LOG(ERR, "flow tables with hash creation failed.");
err = ENOMEM;
return err;
}
- sh->flow_tbls->ctx = sh;
#ifndef HAVE_MLX5DV_DR
struct rte_flow_error error;
struct rte_eth_dev *dev = &rte_eth_devices[priv->dev_data->port_id];
struct mlx5_proc_priv *ppriv;
size_t ppriv_size;
+ mlx5_proc_priv_uninit(dev);
/*
* UAR register table follows the process private structure. BlueFlame
* registers for Tx queues are stored in the table.
* If all the flows are already flushed in the device stop stage,
* then this will return directly without any action.
*/
- mlx5_flow_list_flush(dev, &priv->flows, true);
+ mlx5_flow_list_flush(dev, MLX5_FLOW_TYPE_GEN, true);
mlx5_action_handle_flush(dev);
mlx5_flow_meter_flush(dev, NULL);
/* Prevent crashes when queues are still in use. */
if (priv->mreg_cp_tbl)
mlx5_hlist_destroy(priv->mreg_cp_tbl);
mlx5_mprq_free_mp(dev);
+ if (priv->sh->ct_mng)
+ mlx5_flow_aso_ct_mng_close(priv->sh);
mlx5_os_free_shared_dr(priv);
if (priv->rss_conf.rss_key != NULL)
mlx5_free(priv->rss_conf.rss_key);
if (ret)
DRV_LOG(WARNING, "port %u some flows still remain",
dev->data->port_id);
- mlx5_cache_list_destroy(&priv->hrxqs);
+ if (priv->hrxqs)
+ mlx5_list_destroy(priv->hrxqs);
/*
* Free the shared context in last turn, because the cleanup
* routines above may use some shared fields, like
config->max_dump_files_num = tmp;
} else if (strcmp(MLX5_LRO_TIMEOUT_USEC, key) == 0) {
config->lro.timeout = tmp;
- } else if (strcmp(MLX5_CLASS_ARG_NAME, key) == 0) {
+ } else if (strcmp(RTE_DEVARGS_KEY_CLASS, key) == 0) {
DRV_LOG(DEBUG, "class argument is %s.", val);
} else if (strcmp(MLX5_HP_BUF_SIZE, key) == 0) {
config->log_hp_size = tmp;
config->sys_mem_en = !!tmp;
} else if (strcmp(MLX5_DECAP_EN, key) == 0) {
config->decap_en = !!tmp;
+ } else if (strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) == 0) {
+ config->allow_duplicate_pattern = !!tmp;
} else {
DRV_LOG(WARNING, "%s: unknown parameter", key);
rte_errno = EINVAL;
MLX5_REPRESENTOR,
MLX5_MAX_DUMP_FILES_NUM,
MLX5_LRO_TIMEOUT_USEC,
- MLX5_CLASS_ARG_NAME,
+ RTE_DEVARGS_KEY_CLASS,
MLX5_HP_BUF_SIZE,
MLX5_RECLAIM_MEM,
MLX5_SYS_MEM_EN,
MLX5_DECAP_EN,
+ MLX5_ALLOW_DUPLICATE_PATTERN,
NULL,
};
struct rte_kvargs *kvlist;
};
/* Initialize driver log type. */
-RTE_LOG_REGISTER(mlx5_logtype, pmd.net.mlx5, NOTICE)
+RTE_LOG_REGISTER_DEFAULT(mlx5_logtype, NOTICE)
/**
* Driver initialization routine.