Skip to content

Commit

Permalink
net/mlx5: workaround drop action with old kernel
Browse files Browse the repository at this point in the history
[ upstream commit 45633c4 ]

Currently, there are two types of drop action implementation
in the PMD. One is the DR (Direct Rules) dummy placeholder drop
action and another is the dedicated dummy queue drop action.
When creates flow on the root table with DR drop action, the
action will be converted to MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP
Verbs attribute in rdma-core.

In some inbox systems, MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP Verbs
attribute may not be supported in the kernel driver. Create flow
with drop action on the root table will be failed as it is not
supported. In this case, the dummy queue drop action should be
used instead of DR dummy placeholder drop action.

This commit adds the DR drop action support detect on the root
table. If MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP Verbs is not
supported in the system, a dummy queue will be used as drop
action.

Fixes: da845ae ("net/mlx5: fix drop action for Direct Rules/Verbs")

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
  • Loading branch information
smou-mlnx authored and bluca committed Aug 5, 2021
1 parent 12cc60e commit 53193ae
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 1 deletion.
27 changes: 27 additions & 0 deletions drivers/net/mlx5/linux/mlx5_os.c
Expand Up @@ -651,6 +651,32 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
#endif
}

/**
* DR flow drop action support detect.
*
* @param dev
* Pointer to rte_eth_dev structure.
*
*/
static void
mlx5_flow_drop_action_config(struct rte_eth_dev *dev __rte_unused)
{
#ifdef HAVE_MLX5DV_DR
struct mlx5_priv *priv = dev->data->dev_private;

if (!priv->config.dv_flow_en || !priv->sh->dr_drop_action)
return;
/**
* DR supports drop action placeholder when it is supported;
* otherwise, use the queue drop action.
*/
if (mlx5_flow_discover_dr_action_support(dev))
priv->root_drop_action = priv->drop_queue.hrxq->action;
else
priv->root_drop_action = priv->sh->dr_drop_action;
#endif
}

/**
* Spawn an Ethernet device from Verbs information.
*
Expand Down Expand Up @@ -1587,6 +1613,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
}
rte_spinlock_init(&priv->shared_act_sl);
mlx5_flow_counter_mode_config(eth_dev);
mlx5_flow_drop_action_config(eth_dev);
if (priv->config.dv_flow_en)
eth_dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE;
return eth_dev;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/mlx5/mlx5.h
Expand Up @@ -969,6 +969,7 @@ struct mlx5_priv {
unsigned int reta_idx_n; /* RETA index size. */
struct mlx5_drop drop_queue; /* Flow drop queues. */
uint32_t flows; /* RTE Flow rules. */
void *root_drop_action; /* Pointer to root drop action. */
uint32_t ctrl_flows; /* Control flow rules. */
rte_spinlock_t flow_list_lock;
struct mlx5_obj_ops obj_ops; /* HW objects operations. */
Expand Down
1 change: 1 addition & 0 deletions drivers/net/mlx5/mlx5_flow.h
Expand Up @@ -1429,6 +1429,7 @@ int mlx5_flow_meter_flush(struct rte_eth_dev *dev,
struct rte_mtr_error *error);
int mlx5_flow_dv_discover_counter_offset_support(struct rte_eth_dev *dev);
int mlx5_shared_action_flush(struct rte_eth_dev *dev);
int mlx5_flow_discover_dr_action_support(struct rte_eth_dev *dev);
void mlx5_release_tunnel_hub(struct mlx5_dev_ctx_shared *sh, uint16_t port_id);
int mlx5_alloc_tunnel_hub(struct mlx5_dev_ctx_shared *sh);

Expand Down
70 changes: 69 additions & 1 deletion drivers/net/mlx5/mlx5_flow_dv.c
Expand Up @@ -10840,7 +10840,9 @@ flow_dv_apply(struct rte_eth_dev *dev, struct rte_flow *flow,
#ifdef HAVE_MLX5DV_DR
/* DR supports drop action placeholder. */
MLX5_ASSERT(priv->sh->dr_drop_action);
dv->actions[n++] = priv->sh->dr_drop_action;
dv->actions[n++] = dv->group ?
priv->sh->dr_drop_action :
priv->root_drop_action;
#else
/* For DV we use the explicit drop queue. */
MLX5_ASSERT(priv->drop_queue.hrxq);
Expand Down Expand Up @@ -12567,6 +12569,72 @@ flow_dv_create_policer_rules(struct rte_eth_dev *dev,
flow_dv_destroy_policer_rules(dev, fm, attr);
return -1;
}
/**
* Check whether the DR drop action is supported on the root table or not.
*
* Create a simple flow with DR drop action on root table to validate
* if DR drop action on root table is supported or not.
*
* @param[in] dev
* Pointer to rte_eth_dev structure.
*
* @return
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
int
mlx5_flow_discover_dr_action_support(struct rte_eth_dev *dev)
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_dev_ctx_shared *sh = priv->sh;
struct mlx5_flow_dv_match_params mask = {
.size = sizeof(mask.buf),
};
struct mlx5_flow_dv_match_params value = {
.size = sizeof(value.buf),
};
struct mlx5dv_flow_matcher_attr dv_attr = {
.type = IBV_FLOW_ATTR_NORMAL,
.priority = 0,
.match_criteria_enable = 0,
.match_mask = (void *)&mask,
};
struct mlx5_flow_tbl_resource *tbl = NULL;
void *matcher = NULL;
void *flow = NULL;
int ret = -1;

tbl = flow_dv_tbl_resource_get(dev, 0, 0, 0, false, NULL,
0, 0, NULL);
if (!tbl)
goto err;
dv_attr.match_criteria_enable = flow_dv_matcher_enable(mask.buf);
ret = mlx5_flow_os_create_flow_matcher(sh->ctx, &dv_attr, tbl->obj,
&matcher);
if (ret)
goto err;
ret = mlx5_flow_os_create_flow(matcher, (void *)&value, 1,
&sh->dr_drop_action, &flow);
err:
/*
* If DR drop action is not supported on root table, flow create will
* be failed with EOPNOTSUPP or EPROTONOSUPPORT.
*/
if (!flow) {
if (matcher &&
(errno == EPROTONOSUPPORT || errno == EOPNOTSUPP))
DRV_LOG(INFO, "DR drop action is not supported in root table.");
else
DRV_LOG(ERR, "Unexpected error in DR drop action support detection");
ret = -1;
} else {
claim_zero(mlx5_flow_os_destroy_flow(flow));
}
if (matcher)
claim_zero(mlx5_flow_os_destroy_flow_matcher(matcher));
if (tbl)
flow_dv_tbl_resource_release(MLX5_SH(dev), tbl);
return ret;
}

/**
* Validate the batch counter support in root table.
Expand Down

0 comments on commit 53193ae

Please sign in to comment.