net/mlx5: add more details to flow dump
Currently the flow dump provides few information about actions - just the pointers. Add implementations to display details for counter, modify_hdr and encap_decap actions. For counter, the regular flow operation query is engaged and the counter content information is provided, including hits and bytes values.For modify_hdr, encap_and decap actions, the information stored in the ipool objects is dumped. There are the formats of information presented in the dump: Counter: rec_type,id,hits,bytes Modify_hdr: rec_type,id,actions_number,actions Encap_decap: rec_type,id,buf Signed-off-by: Haifei Luo <haifeil@nvidia.com> Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
This commit is contained in:
parent
1c196da274
commit
5db9318f76
@ -1398,6 +1398,13 @@ struct rte_hairpin_peer_info {
|
||||
uint16_t manual_bind;
|
||||
};
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
enum dr_dump_rec_type {
|
||||
DR_DUMP_REC_TYPE_PMD_PKT_REFORMAT = 4410,
|
||||
DR_DUMP_REC_TYPE_PMD_MODIFY_HDR = 4420,
|
||||
DR_DUMP_REC_TYPE_PMD_COUNTER = 4430,
|
||||
};
|
||||
|
||||
/* mlx5.c */
|
||||
|
||||
int mlx5_getenv_int(const char *);
|
||||
@ -1629,6 +1636,14 @@ int mlx5_counter_query(struct rte_eth_dev *dev, uint32_t cnt,
|
||||
bool clear, uint64_t *pkts, uint64_t *bytes);
|
||||
int mlx5_flow_dev_dump(struct rte_eth_dev *dev, struct rte_flow *flow,
|
||||
FILE *file, struct rte_flow_error *error);
|
||||
int save_dump_file(const unsigned char *data, uint32_t size,
|
||||
uint32_t type, uint32_t id, void *arg, FILE *file);
|
||||
int mlx5_flow_query_counter(struct rte_eth_dev *dev, struct rte_flow *flow,
|
||||
struct rte_flow_query_count *count, struct rte_flow_error *error);
|
||||
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
|
||||
int mlx5_flow_dev_dump_ipool(struct rte_eth_dev *dev, struct rte_flow *flow,
|
||||
FILE *file, struct rte_flow_error *error);
|
||||
#endif
|
||||
void mlx5_flow_rxq_dynf_metadata_set(struct rte_eth_dev *dev);
|
||||
int mlx5_flow_get_aged_flows(struct rte_eth_dev *dev, void **contexts,
|
||||
uint32_t nb_contexts, struct rte_flow_error *error);
|
||||
|
@ -7898,6 +7898,157 @@ mlx5_flow_discover_mreg_c(struct rte_eth_dev *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
save_dump_file(const uint8_t *data, uint32_t size,
|
||||
uint32_t type, uint32_t id, void *arg, FILE *file)
|
||||
{
|
||||
char line[BUF_SIZE];
|
||||
uint32_t out = 0;
|
||||
uint32_t k;
|
||||
uint32_t actions_num;
|
||||
struct rte_flow_query_count *count;
|
||||
|
||||
memset(line, 0, BUF_SIZE);
|
||||
switch (type) {
|
||||
case DR_DUMP_REC_TYPE_PMD_MODIFY_HDR:
|
||||
actions_num = *(uint32_t *)(arg);
|
||||
out += snprintf(line + out, BUF_SIZE - out, "%d,0x%x,%d,",
|
||||
type, id, actions_num);
|
||||
break;
|
||||
case DR_DUMP_REC_TYPE_PMD_PKT_REFORMAT:
|
||||
out += snprintf(line + out, BUF_SIZE - out, "%d,0x%x,",
|
||||
type, id);
|
||||
break;
|
||||
case DR_DUMP_REC_TYPE_PMD_COUNTER:
|
||||
count = (struct rte_flow_query_count *)arg;
|
||||
fprintf(file, "%d,0x%x,%" PRIu64 ",%" PRIu64 "\n", type,
|
||||
id, count->hits, count->bytes);
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (k = 0; k < size; k++) {
|
||||
/* Make sure we do not overrun the line buffer length. */
|
||||
if (out >= BUF_SIZE - 4) {
|
||||
line[out] = '\0';
|
||||
break;
|
||||
}
|
||||
out += snprintf(line + out, BUF_SIZE - out, "%02x",
|
||||
(data[k]) & 0xff);
|
||||
}
|
||||
fprintf(file, "%s\n", line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mlx5_flow_query_counter(struct rte_eth_dev *dev, struct rte_flow *flow,
|
||||
struct rte_flow_query_count *count, struct rte_flow_error *error)
|
||||
{
|
||||
struct rte_flow_action action[2];
|
||||
enum mlx5_flow_drv_type ftype;
|
||||
const struct mlx5_flow_driver_ops *fops;
|
||||
|
||||
if (!flow) {
|
||||
return rte_flow_error_set(error, ENOENT,
|
||||
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
|
||||
NULL,
|
||||
"invalid flow handle");
|
||||
}
|
||||
action[0].type = RTE_FLOW_ACTION_TYPE_COUNT;
|
||||
action[1].type = RTE_FLOW_ACTION_TYPE_END;
|
||||
if (flow->counter) {
|
||||
memset(count, 0, sizeof(struct rte_flow_query_count));
|
||||
ftype = (enum mlx5_flow_drv_type)(flow->drv_type);
|
||||
MLX5_ASSERT(ftype > MLX5_FLOW_TYPE_MIN &&
|
||||
ftype < MLX5_FLOW_TYPE_MAX);
|
||||
fops = flow_get_drv_ops(ftype);
|
||||
return fops->query(dev, flow, action, count, error);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
|
||||
/**
|
||||
* Dump flow ipool data to file
|
||||
*
|
||||
* @param[in] dev
|
||||
* The pointer to Ethernet device.
|
||||
* @param[in] file
|
||||
* A pointer to a file for output.
|
||||
* @param[out] error
|
||||
* Perform verbose error reporting if not NULL. PMDs initialize this
|
||||
* structure in case of error only.
|
||||
* @return
|
||||
* 0 on success, a negative value otherwise.
|
||||
*/
|
||||
int
|
||||
mlx5_flow_dev_dump_ipool(struct rte_eth_dev *dev,
|
||||
struct rte_flow *flow, FILE *file,
|
||||
struct rte_flow_error *error)
|
||||
{
|
||||
struct mlx5_priv *priv = dev->data->dev_private;
|
||||
struct mlx5_flow_dv_modify_hdr_resource *modify_hdr;
|
||||
struct mlx5_flow_dv_encap_decap_resource *encap_decap;
|
||||
uint32_t handle_idx;
|
||||
struct mlx5_flow_handle *dh;
|
||||
struct rte_flow_query_count count;
|
||||
uint32_t actions_num;
|
||||
const uint8_t *data;
|
||||
size_t size;
|
||||
uint32_t id;
|
||||
uint32_t type;
|
||||
|
||||
if (!flow) {
|
||||
return rte_flow_error_set(error, ENOENT,
|
||||
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
|
||||
NULL,
|
||||
"invalid flow handle");
|
||||
}
|
||||
handle_idx = flow->dev_handles;
|
||||
while (handle_idx) {
|
||||
dh = mlx5_ipool_get(priv->sh->ipool
|
||||
[MLX5_IPOOL_MLX5_FLOW], handle_idx);
|
||||
if (!dh)
|
||||
continue;
|
||||
handle_idx = dh->next.next;
|
||||
id = (uint32_t)(uintptr_t)dh->drv_flow;
|
||||
|
||||
/* query counter */
|
||||
type = DR_DUMP_REC_TYPE_PMD_COUNTER;
|
||||
if (!mlx5_flow_query_counter(dev, flow, &count, error))
|
||||
save_dump_file(NULL, 0, type,
|
||||
id, (void *)&count, file);
|
||||
|
||||
/* Get modify_hdr and encap_decap buf from ipools. */
|
||||
encap_decap = NULL;
|
||||
modify_hdr = dh->dvh.modify_hdr;
|
||||
|
||||
if (dh->dvh.rix_encap_decap) {
|
||||
encap_decap = mlx5_ipool_get(priv->sh->ipool
|
||||
[MLX5_IPOOL_DECAP_ENCAP],
|
||||
dh->dvh.rix_encap_decap);
|
||||
}
|
||||
if (modify_hdr) {
|
||||
data = (const uint8_t *)modify_hdr->actions;
|
||||
size = (size_t)(modify_hdr->actions_num) * 8;
|
||||
actions_num = modify_hdr->actions_num;
|
||||
type = DR_DUMP_REC_TYPE_PMD_MODIFY_HDR;
|
||||
save_dump_file(data, size, type, id,
|
||||
(void *)(&actions_num), file);
|
||||
}
|
||||
if (encap_decap) {
|
||||
data = encap_decap->buf;
|
||||
size = encap_decap->size;
|
||||
type = DR_DUMP_REC_TYPE_PMD_PKT_REFORMAT;
|
||||
save_dump_file(data, size, type,
|
||||
id, NULL, file);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Dump flow raw hw data to file
|
||||
*
|
||||
@ -7922,6 +8073,9 @@ mlx5_flow_dev_dump(struct rte_eth_dev *dev, struct rte_flow *flow_idx,
|
||||
int ret;
|
||||
struct mlx5_flow_handle *dh;
|
||||
struct rte_flow *flow;
|
||||
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
|
||||
uint32_t idx;
|
||||
#endif
|
||||
|
||||
if (!priv->config.dv_flow_en) {
|
||||
if (fputs("device dv flow disabled\n", file) <= 0)
|
||||
@ -7930,16 +8084,25 @@ mlx5_flow_dev_dump(struct rte_eth_dev *dev, struct rte_flow *flow_idx,
|
||||
}
|
||||
|
||||
/* dump all */
|
||||
if (!flow_idx)
|
||||
if (!flow_idx) {
|
||||
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
|
||||
ILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_RTE_FLOW],
|
||||
priv->flows, idx, flow, next)
|
||||
mlx5_flow_dev_dump_ipool(dev, flow, file, error);
|
||||
#endif
|
||||
return mlx5_devx_cmd_flow_dump(sh->fdb_domain,
|
||||
sh->rx_domain,
|
||||
sh->tx_domain, file);
|
||||
}
|
||||
/* dump one */
|
||||
flow = mlx5_ipool_get(priv->sh->ipool
|
||||
[MLX5_IPOOL_RTE_FLOW], (uintptr_t)(void *)flow_idx);
|
||||
if (!flow)
|
||||
return -ENOENT;
|
||||
|
||||
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
|
||||
mlx5_flow_dev_dump_ipool(dev, flow, file, error);
|
||||
#endif
|
||||
handle_idx = flow->dev_handles;
|
||||
while (handle_idx) {
|
||||
dh = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],
|
||||
|
Loading…
x
Reference in New Issue
Block a user