age_info = &sh->port[i].age_info;
if (!MLX5_AGE_GET(age_info, MLX5_AGE_EVENT_NEW))
continue;
- if (MLX5_AGE_GET(age_info, MLX5_AGE_TRIGGER))
+ MLX5_AGE_UNSET(age_info, MLX5_AGE_EVENT_NEW);
+ if (MLX5_AGE_GET(age_info, MLX5_AGE_TRIGGER)) {
+ MLX5_AGE_UNSET(age_info, MLX5_AGE_TRIGGER);
rte_eth_dev_callback_process
(&rte_eth_devices[sh->port[i].devx_ih_port_id],
RTE_ETH_EVENT_FLOW_AGED, NULL);
- age_info->flags = 0;
+ }
}
}
+/*
+ * 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.
*
* @param[in] sh
* Pointer to mlx5_dev_ctx_shared object.
- * @param[in] sh
+ * @param[in] config
* Pointer to user dev config.
*/
static void
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);
.hairpin_queue_peer_update = mlx5_hairpin_queue_peer_update,
.hairpin_queue_peer_bind = mlx5_hairpin_queue_peer_bind,
.hairpin_queue_peer_unbind = mlx5_hairpin_queue_peer_unbind,
+ .get_monitor_addr = mlx5_get_monitor_addr,
};
/* Available operations from secondary process. */
.hairpin_queue_peer_update = mlx5_hairpin_queue_peer_update,
.hairpin_queue_peer_bind = mlx5_hairpin_queue_peer_bind,
.hairpin_queue_peer_unbind = mlx5_hairpin_queue_peer_unbind,
+ .get_monitor_addr = mlx5_get_monitor_addr,
};
/**