mlx5_os_set_reg_mr_cb(&sh->share_cache.reg_mr_cb,
&sh->share_cache.dereg_mr_cb);
mlx5_os_dev_shared_handler_install(sh);
+ sh->cnt_id_tbl = mlx5_l3t_create(MLX5_L3T_TYPE_DWORD);
+ if (!sh->cnt_id_tbl) {
+ err = rte_errno;
+ goto error;
+ }
mlx5_flow_aging_init(sh);
mlx5_flow_counters_mng_init(sh);
mlx5_flow_ipool_create(sh, config);
error:
pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
MLX5_ASSERT(sh);
+ if (sh->cnt_id_tbl) {
+ mlx5_l3t_destroy(sh->cnt_id_tbl);
+ sh->cnt_id_tbl = NULL;
+ }
if (sh->tis)
claim_zero(mlx5_devx_cmd_destroy(sh->tis));
if (sh->td)
mlx5_flow_counters_mng_close(sh);
mlx5_flow_ipool_destroy(sh);
mlx5_os_dev_shared_handler_uninstall(sh);
+ if (sh->cnt_id_tbl) {
+ mlx5_l3t_destroy(sh->cnt_id_tbl);
+ sh->cnt_id_tbl = NULL;
+ }
if (sh->pd)
claim_zero(mlx5_glue->dealloc_pd(sh->pd));
if (sh->tis)
/**
* Search for existed shared counter.
*
- * @param[in] cont
- * Pointer to the relevant counter pool container.
+ * @param[in] dev
+ * Pointer to the Ethernet device structure.
* @param[in] id
* The shared counter ID to search.
* @param[out] ppool
* NULL if not existed, otherwise pointer to the shared extend counter.
*/
static struct mlx5_flow_counter_ext *
-flow_dv_counter_shared_search(struct mlx5_pools_container *cont, uint32_t id,
+flow_dv_counter_shared_search(struct rte_eth_dev *dev, uint32_t id,
struct mlx5_flow_counter_pool **ppool)
{
- struct mlx5_flow_counter_ext *cnt;
- struct mlx5_flow_counter_pool *pool;
- uint32_t i, j;
- uint32_t n_valid = rte_atomic16_read(&cont->n_valid);
+ struct mlx5_priv *priv = dev->data->dev_private;
+ union mlx5_l3t_data data;
+ uint32_t cnt_idx;
- for (i = 0; i < n_valid; i++) {
- pool = cont->pools[i];
- for (j = 0; j < MLX5_COUNTERS_PER_POOL; ++j) {
- cnt = MLX5_GET_POOL_CNT_EXT(pool, j);
- if (cnt->ref_cnt && cnt->shared && cnt->id == id) {
- if (ppool)
- *ppool = cont->pools[i];
- return cnt;
- }
- }
- }
- return NULL;
+ if (mlx5_l3t_get_entry(priv->sh->cnt_id_tbl, id, &data) || !data.dword)
+ return NULL;
+ cnt_idx = data.dword;
+ /*
+ * Shared counters don't have age info. The counter extend is after
+ * the counter datat structure.
+ */
+ return (struct mlx5_flow_counter_ext *)
+ ((flow_dv_counter_get_by_idx(dev, cnt_idx, ppool)) + 1);
}
/**
return 0;
}
if (shared) {
- cnt_ext = flow_dv_counter_shared_search(cont, id, &pool);
+ cnt_ext = flow_dv_counter_shared_search(dev, id, &pool);
if (cnt_ext) {
if (cnt_ext->ref_cnt + 1 == 0) {
rte_errno = E2BIG;
cnt_ext->shared = shared;
cnt_ext->ref_cnt = 1;
cnt_ext->id = id;
+ if (shared) {
+ union mlx5_l3t_data data;
+
+ data.dword = cnt_idx;
+ if (mlx5_l3t_set_entry(priv->sh->cnt_id_tbl, id, &data))
+ return 0;
+ }
}
if (!priv->counter_fallback && !priv->sh->cmng.query_thread_on)
/* Start the asynchronous batch query by the host thread. */
static void
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 = NULL;
struct mlx5_flow_counter *cnt;
struct mlx5_flow_counter_ext *cnt_ext = NULL;
MLX5_ASSERT(pool);
if (counter < MLX5_CNT_BATCH_OFFSET) {
cnt_ext = MLX5_CNT_TO_CNT_EXT(pool, cnt);
- if (cnt_ext && --cnt_ext->ref_cnt)
- return;
+ if (cnt_ext) {
+ if (--cnt_ext->ref_cnt)
+ return;
+ if (cnt_ext->shared)
+ mlx5_l3t_clear_entry(priv->sh->cnt_id_tbl,
+ cnt_ext->id);
+ }
}
if (IS_AGE_POOL(pool))
flow_dv_counter_remove_from_age(dev, counter, cnt);