@@ -556,6 +556,7 @@ struct mlx5_priv {
uint8_t skip_default_rss_reta; /* Skip configuration of default reta. */
uint8_t fdb_def_rule; /* Whether fdb jump to table 1 is configured. */
struct mlx5_mp_id mp_id; /* ID of a multi-process process */
+ LIST_HEAD(fdir, mlx5_fdir_flow) fdir_flows; /* fdir flows. */
};
#define PORT_ID(priv) ((priv)->dev_data->port_id)
@@ -4491,6 +4491,7 @@ struct rte_flow *
struct rte_flow *flow)
{
struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_fdir_flow *priv_fdir_flow = NULL;
/*
* Update RX queue flags only if port is started, otherwise it is
@@ -4505,7 +4506,17 @@ struct rte_flow *
if (list)
TAILQ_REMOVE(list, flow, next);
flow_mreg_del_copy_action(dev, flow);
- rte_free(flow->fdir);
+ if (flow->fdir) {
+ LIST_FOREACH(priv_fdir_flow, &priv->fdir_flows, next) {
+ if (priv_fdir_flow->flow == flow)
+ break;
+ }
+ if (priv_fdir_flow) {
+ LIST_REMOVE(priv_fdir_flow, next);
+ rte_free(priv_fdir_flow->fdir);
+ rte_free(priv_fdir_flow);
+ }
+ }
rte_free(flow);
}
@@ -5189,12 +5200,14 @@ struct rte_flow *
{
struct mlx5_priv *priv = dev->data->dev_private;
struct rte_flow *flow = NULL;
+ struct mlx5_fdir_flow *priv_fdir_flow = NULL;
MLX5_ASSERT(fdir_flow);
- TAILQ_FOREACH(flow, &priv->flows, next) {
- if (flow->fdir && !flow_fdir_cmp(flow->fdir, fdir_flow)) {
+ LIST_FOREACH(priv_fdir_flow, &priv->fdir_flows, next) {
+ if (!flow_fdir_cmp(priv_fdir_flow->fdir, fdir_flow)) {
DRV_LOG(DEBUG, "port %u found FDIR flow %p",
dev->data->port_id, (void *)flow);
+ flow = priv_fdir_flow->flow;
break;
}
}
@@ -5219,6 +5232,7 @@ struct rte_flow *
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_fdir *fdir_flow;
struct rte_flow *flow;
+ struct mlx5_fdir_flow *priv_fdir_flow = NULL;
int ret;
fdir_flow = rte_zmalloc(__func__, sizeof(*fdir_flow), 0);
@@ -5234,17 +5248,26 @@ struct rte_flow *
rte_errno = EEXIST;
goto error;
}
+ priv_fdir_flow = rte_zmalloc(__func__, sizeof(struct mlx5_fdir_flow),
+ 0);
+ if (!priv_fdir_flow) {
+ rte_errno = ENOMEM;
+ goto error;
+ }
flow = flow_list_create(dev, &priv->flows, &fdir_flow->attr,
fdir_flow->items, fdir_flow->actions, true,
NULL);
if (!flow)
goto error;
- MLX5_ASSERT(!flow->fdir);
- flow->fdir = fdir_flow;
+ flow->fdir = 1;
+ priv_fdir_flow->fdir = fdir_flow;
+ priv_fdir_flow->flow = flow;
+ LIST_INSERT_HEAD(&priv->fdir_flows, priv_fdir_flow, next);
DRV_LOG(DEBUG, "port %u created FDIR flow %p",
dev->data->port_id, (void *)flow);
return 0;
error:
+ rte_free(priv_fdir_flow);
rte_free(fdir_flow);
return -rte_errno;
}
@@ -5269,17 +5292,26 @@ struct rte_flow *
struct mlx5_fdir fdir_flow = {
.attr.group = 0,
};
+ struct mlx5_fdir_flow *priv_fdir_flow = NULL;
int ret;
ret = flow_fdir_filter_convert(dev, fdir_filter, &fdir_flow);
if (ret)
return -rte_errno;
- flow = flow_fdir_filter_lookup(dev, &fdir_flow);
- if (!flow) {
- rte_errno = ENOENT;
- return -rte_errno;
+ LIST_FOREACH(priv_fdir_flow, &priv->fdir_flows, next) {
+ /* Find the fdir in priv list */
+ if (!flow_fdir_cmp(priv_fdir_flow->fdir, &fdir_flow))
+ break;
}
+ if (!priv_fdir_flow)
+ return 0;
+ LIST_REMOVE(priv_fdir_flow, next);
+ flow = priv_fdir_flow->flow;
+ /* Fdir resource will be releasd after flow destroy. */
+ flow->fdir = 0;
flow_list_destroy(dev, &priv->flows, flow);
+ rte_free(priv_fdir_flow->fdir);
+ rte_free(priv_fdir_flow);
DRV_LOG(DEBUG, "port %u deleted FDIR flow %p",
dev->data->port_id, (void *)flow);
return 0;
@@ -5318,8 +5350,16 @@ struct rte_flow *
flow_fdir_filter_flush(struct rte_eth_dev *dev)
{
struct mlx5_priv *priv = dev->data->dev_private;
-
- mlx5_flow_list_flush(dev, &priv->flows, false);
+ struct mlx5_fdir_flow *priv_fdir_flow = NULL;
+
+ while (!LIST_EMPTY(&priv->fdir_flows)) {
+ priv_fdir_flow = LIST_FIRST(&priv->fdir_flows);
+ LIST_REMOVE(priv_fdir_flow, next);
+ priv_fdir_flow->flow->fdir = 0;
+ flow_list_destroy(dev, &priv->flows, priv_fdir_flow->flow);
+ rte_free(priv_fdir_flow->fdir);
+ rte_free(priv_fdir_flow);
+ }
}
/**
@@ -751,6 +751,13 @@ struct mlx5_flow_meter_profile {
uint32_t ref_cnt; /**< Use count. */
};
+/* Fdir flow struture */
+struct mlx5_fdir_flow {
+ LIST_ENTRY(mlx5_fdir_flow) next; /* Pointer to the next element. */
+ struct mlx5_fdir *fdir; /* Pointer to fdir. */
+ struct rte_flow *flow; /* Pointer to flow. */
+};
+
/* Flow structure. */
struct rte_flow {
TAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */
@@ -762,7 +769,7 @@ struct rte_flow {
uint16_t meter; /**< Holds flow meter id. */
uint32_t dev_handles;
/**< Device flow handles that are part of the flow. */
- struct mlx5_fdir *fdir; /**< Pointer to associated FDIR if any. */
+ uint32_t fdir:1; /**< Identifier of associated FDIR if any. */
uint32_t hairpin_flow_id; /**< The flow id used for hairpin. */
uint32_t copy_applied:1; /**< The MARK copy Flow os applied. */
};