struct rte_flow_error *error)
{
size_t size = 0;
+ uint32_t handle_idx = 0;
struct mlx5_flow *dev_flow;
struct mlx5_flow_handle *dev_handle;
struct mlx5_priv *priv = dev->data->dev_private;
"not free temporary device flow");
return NULL;
}
- dev_handle = rte_calloc(__func__, 1, MLX5_FLOW_HANDLE_VERBS_SIZE, 0);
+ dev_handle = mlx5_ipool_zmalloc(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],
+ &handle_idx);
if (!dev_handle) {
rte_flow_error_set(error, ENOMEM,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
/* No multi-thread supporting. */
dev_flow = &((struct mlx5_flow *)priv->inter_flows)[priv->flow_idx++];
dev_flow->handle = dev_handle;
+ dev_flow->handle_idx = handle_idx;
/* Memcpy is used, only size needs to be cleared to 0. */
dev_flow->verbs.size = 0;
dev_flow->verbs.attr.num_of_specs = 0;
static void
flow_verbs_remove(struct rte_eth_dev *dev, struct rte_flow *flow)
{
+ struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_handle *handle;
+ uint32_t handle_idx;
if (!flow)
return;
- LIST_FOREACH(handle, &flow->dev_handles, next) {
+ SILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW], flow->dev_handles,
+ handle_idx, handle, next) {
if (handle->ib_flow) {
claim_zero(mlx5_glue->destroy_flow(handle->ib_flow));
handle->ib_flow = NULL;
}
+ /* hrxq is union, don't touch it only the flag is set. */
if (handle->hrxq) {
- if (handle->act_flags & MLX5_FLOW_ACTION_DROP)
+ if (handle->act_flags & MLX5_FLOW_ACTION_DROP) {
mlx5_hrxq_drop_release(dev);
- else
+ handle->hrxq = 0;
+ } else if (handle->act_flags &
+ (MLX5_FLOW_ACTION_QUEUE |
+ MLX5_FLOW_ACTION_RSS)) {
mlx5_hrxq_release(dev, handle->hrxq);
- handle->hrxq = NULL;
+ handle->hrxq = 0;
+ }
}
if (handle->vf_vlan.tag && handle->vf_vlan.created)
mlx5_vlan_vmwa_release(dev, &handle->vf_vlan);
static void
flow_verbs_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
{
+ struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_handle *handle;
if (!flow)
return;
flow_verbs_remove(dev, flow);
- while (!LIST_EMPTY(&flow->dev_handles)) {
- handle = LIST_FIRST(&flow->dev_handles);
- LIST_REMOVE(handle, next);
- rte_free(handle);
+ while (flow->dev_handles) {
+ uint32_t tmp_idx = flow->dev_handles;
+
+ handle = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],
+ tmp_idx);
+ if (!handle)
+ return;
+ flow->dev_handles = handle->next.next;
+ mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],
+ tmp_idx);
}
if (flow->counter) {
flow_verbs_counter_release(dev, flow->counter);
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_handle *handle;
struct mlx5_flow *dev_flow;
+ struct mlx5_hrxq *hrxq;
+ uint32_t dev_handles;
int err;
int idx;
dev_flow = &((struct mlx5_flow *)priv->inter_flows)[idx];
handle = dev_flow->handle;
if (handle->act_flags & MLX5_FLOW_ACTION_DROP) {
- handle->hrxq = mlx5_hrxq_drop_new(dev);
- if (!handle->hrxq) {
+ hrxq = mlx5_hrxq_drop_new(dev);
+ if (!hrxq) {
rte_flow_error_set
(error, errno,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
goto error;
}
} else {
- struct mlx5_hrxq *hrxq;
+ uint32_t hrxq_idx;
MLX5_ASSERT(flow->rss.queue);
- hrxq = mlx5_hrxq_get(dev, flow->rss.key,
+ hrxq_idx = mlx5_hrxq_get(dev, flow->rss.key,
MLX5_RSS_HASH_KEY_LEN,
dev_flow->hash_fields,
(*flow->rss.queue),
flow->rss.queue_num);
- if (!hrxq)
- hrxq = mlx5_hrxq_new(dev, flow->rss.key,
+ if (!hrxq_idx)
+ hrxq_idx = mlx5_hrxq_new(dev, flow->rss.key,
MLX5_RSS_HASH_KEY_LEN,
dev_flow->hash_fields,
(*flow->rss.queue),
flow->rss.queue_num,
!!(handle->layers &
MLX5_FLOW_LAYER_TUNNEL));
+ hrxq = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_HRXQ],
+ hrxq_idx);
if (!hrxq) {
rte_flow_error_set
(error, rte_errno,
"cannot get hash queue");
goto error;
}
- handle->hrxq = hrxq;
+ handle->hrxq = hrxq_idx;
}
- handle->ib_flow = mlx5_glue->create_flow(handle->hrxq->qp,
+ MLX5_ASSERT(hrxq);
+ handle->ib_flow = mlx5_glue->create_flow(hrxq->qp,
&dev_flow->verbs.attr);
if (!handle->ib_flow) {
rte_flow_error_set(error, errno,
return 0;
error:
err = rte_errno; /* Save rte_errno before cleanup. */
- LIST_FOREACH(handle, &flow->dev_handles, next) {
+ SILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW], flow->dev_handles,
+ dev_handles, handle, next) {
+ /* hrxq is union, don't touch it only the flag is set. */
if (handle->hrxq) {
- if (handle->act_flags & MLX5_FLOW_ACTION_DROP)
+ if (handle->act_flags & MLX5_FLOW_ACTION_DROP) {
mlx5_hrxq_drop_release(dev);
- else
+ handle->hrxq = 0;
+ } else if (handle->act_flags &
+ (MLX5_FLOW_ACTION_QUEUE |
+ MLX5_FLOW_ACTION_RSS)) {
mlx5_hrxq_release(dev, handle->hrxq);
- handle->hrxq = NULL;
+ handle->hrxq = 0;
+ }
}
if (handle->vf_vlan.tag && handle->vf_vlan.created)
mlx5_vlan_vmwa_release(dev, &handle->vf_vlan);