@@ -118,6 +118,7 @@ static const struct verbs_context_ops mlx5_ctx_common_ops = {
.alloc_dm = mlx5_alloc_dm,
.alloc_parent_domain = mlx5_alloc_parent_domain,
.alloc_td = mlx5_alloc_td,
+ .attach_counters_point_flow = mlx5_attach_counters_point_flow,
.close_xrcd = mlx5_close_xrcd,
.create_counters = mlx5_create_counters,
.create_cq_ex = mlx5_create_cq_ex,
@@ -535,8 +535,17 @@ struct mlx5_rwq {
int wq_sig;
};
+struct mlx5_counter_node {
+ uint32_t index;
+ struct list_node entry;
+ enum ibv_counter_description desc;
+};
+
struct mlx5_counters {
struct verbs_counters vcounters;
+ struct list_head counters_list;
+ pthread_mutex_t lock;
+ uint32_t ncounters;
};
static inline int mlx5_ilog2(int n)
@@ -846,6 +855,9 @@ void *mlx5_mmap(struct mlx5_uar_info *uar, int index,
struct ibv_counters *mlx5_create_counters(struct ibv_context *context,
struct ibv_counters_init_attr *init_attr);
int mlx5_destroy_counters(struct ibv_counters *counters);
+int mlx5_attach_counters_point_flow(struct ibv_counters *counters,
+ struct ibv_counter_attach_attr *attr,
+ struct ibv_flow *flow);
static inline void *mlx5_find_uidx(struct mlx5_context *ctx, uint32_t uidx)
{
@@ -3255,6 +3255,7 @@ struct ibv_counters *mlx5_create_counters(struct ibv_context *context,
return NULL;
}
+ pthread_mutex_init(&mcntrs->lock, NULL);
ret = ibv_cmd_create_counters(context,
init_attr,
&mcntrs->vcounters,
@@ -3262,6 +3263,8 @@ struct ibv_counters *mlx5_create_counters(struct ibv_context *context,
if (ret)
goto err_create;
+ list_head_init(&mcntrs->counters_list);
+
return &mcntrs->vcounters.counters;
err_create:
@@ -3272,12 +3275,51 @@ err_create:
int mlx5_destroy_counters(struct ibv_counters *counters)
{
struct mlx5_counters *mcntrs = to_mcounters(counters);
+ struct mlx5_counter_node *tmp, *cntrs_node;
int ret;
ret = ibv_cmd_destroy_counters(&mcntrs->vcounters);
if (ret)
return ret;
+ list_for_each_safe(&mcntrs->counters_list, cntrs_node, tmp, entry) {
+ list_del(&cntrs_node->entry);
+ free(cntrs_node);
+ }
+
free(mcntrs);
return 0;
}
+
+int mlx5_attach_counters_point_flow(struct ibv_counters *counters,
+ struct ibv_counter_attach_attr *attr,
+ struct ibv_flow *flow)
+{
+ struct mlx5_counters *mcntrs = to_mcounters(counters);
+ struct mlx5_counter_node *cntrs_node;
+
+ /* The driver supports only the static binding mode as part of ibv_create_flow */
+ if (flow)
+ return ENOTSUP;
+
+ if (!check_comp_mask(attr->comp_mask, 0))
+ return EOPNOTSUPP;
+
+ /* Check whether the attached counter is supported */
+ if (attr->counter_desc < IBV_COUNTER_PACKETS ||
+ attr->counter_desc > IBV_COUNTER_BYTES)
+ return ENOTSUP;
+
+ cntrs_node = calloc(1, sizeof(*cntrs_node));
+ if (!cntrs_node)
+ return ENOMEM;
+
+ cntrs_node->index = attr->index;
+ cntrs_node->desc = attr->counter_desc;
+ pthread_mutex_lock(&mcntrs->lock);
+ list_add(&mcntrs->counters_list, &cntrs_node->entry);
+ mcntrs->ncounters++;
+ pthread_mutex_unlock(&mcntrs->lock);
+
+ return 0;
+}