numam-dpdk/drivers/net/mlx5/mlx5_devx_cmds.c
Moti Haimovsky f5bf91de73 net/mlx5: support flow counters using devx
This commit adds counters support when creating flows via direct
verbs. The implementation uses devx interface in order to create
query and delete the counters.
This support requires MLNX_OFED_LINUX-4.5-0.1.0.1 installation.

Signed-off-by: Moti Haimovsky <motih@mellanox.com>
Acked-by: Shahaf Shuler <shahafs@mellanox.com>
2019-01-14 17:44:29 +01:00

108 lines
3.0 KiB
C

// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2018 Mellanox Technologies, Ltd */
#include <rte_flow_driver.h>
#include "mlx5.h"
#include "mlx5_glue.h"
#include "mlx5_prm.h"
/**
* Allocate flow counters via devx interface.
*
* @param[in] ctx
* ibv contexts returned from mlx5dv_open_device.
* @param dcs
* Pointer to counters properties structure to be filled by the routine.
*
* @return
* 0 on success, a negative value otherwise.
*/
int mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx,
struct mlx5_devx_counter_set *dcs)
{
uint32_t in[MLX5_ST_SZ_DW(alloc_flow_counter_in)] = {0};
uint32_t out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {0};
int status, syndrome;
MLX5_SET(alloc_flow_counter_in, in, opcode,
MLX5_CMD_OP_ALLOC_FLOW_COUNTER);
dcs->obj = mlx5_glue->devx_obj_create(ctx, in,
sizeof(in), out, sizeof(out));
if (!dcs->obj)
return -errno;
status = MLX5_GET(query_flow_counter_out, out, status);
syndrome = MLX5_GET(query_flow_counter_out, out, syndrome);
if (status) {
DRV_LOG(DEBUG, "Failed to create devx counters, "
"status %x, syndrome %x", status, syndrome);
return -1;
}
dcs->id = MLX5_GET(alloc_flow_counter_out,
out, flow_counter_id);
return 0;
}
/**
* Free flow counters obtained via devx interface.
*
* @param[in] obj
* devx object that was obtained from mlx5_devx_cmd_fc_alloc.
*
* @return
* 0 on success, a negative value otherwise.
*/
int mlx5_devx_cmd_flow_counter_free(struct mlx5dv_devx_obj *obj)
{
return mlx5_glue->devx_obj_destroy(obj);
}
/**
* Query flow counters values.
*
* @param[in] dcs
* devx object that was obtained from mlx5_devx_cmd_fc_alloc.
* @param[in] clear
* Whether hardware should clear the counters after the query or not.
* @param pkts
* The number of packets that matched the flow.
* @param bytes
* The number of bytes that matched the flow.
*
* @return
* 0 on success, a negative value otherwise.
*/
int
mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_counter_set *dcs,
int clear __rte_unused,
uint64_t *pkts, uint64_t *bytes)
{
uint32_t out[MLX5_ST_SZ_BYTES(query_flow_counter_out) +
MLX5_ST_SZ_BYTES(traffic_counter)] = {0};
uint32_t in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {0};
void *stats;
int status, syndrome, rc;
MLX5_SET(query_flow_counter_in, in, opcode,
MLX5_CMD_OP_QUERY_FLOW_COUNTER);
MLX5_SET(query_flow_counter_in, in, op_mod, 0);
MLX5_SET(query_flow_counter_in, in, flow_counter_id, dcs->id);
rc = mlx5_glue->devx_obj_query(dcs->obj,
in, sizeof(in), out, sizeof(out));
if (rc)
return rc;
status = MLX5_GET(query_flow_counter_out, out, status);
syndrome = MLX5_GET(query_flow_counter_out, out, syndrome);
if (status) {
DRV_LOG(DEBUG, "Failed to query devx counters, "
"id %d, status %x, syndrome = %x",
status, syndrome, dcs->id);
return -1;
}
stats = MLX5_ADDR_OF(query_flow_counter_out,
out, flow_statistics);
*pkts = MLX5_GET64(traffic_counter, stats, packets);
*bytes = MLX5_GET64(traffic_counter, stats, octets);
return 0;
}