Skip to content

Commit

Permalink
net/mlx5: fix disabling E-Switch default flow rules
Browse files Browse the repository at this point in the history
`fdb_def_rule_en` devarg controls whether mlx5 PMD creates default
E-Switch flow rules for:

- Transferring traffic from wire, VFs and SFs to group 1 (default jump).
- Providing default behavior for application traffic (default SQ miss
  flow rules).

With these flow rules, applications effectively create transfer flow
rules in group 1 and higher (application group is translated to one
higher) allowing for faster insertion on all groups and providing
ability to forward to VF, SF and wire on any group.

By default, these rules are created (`fdb_def_rule_en` == 1).

When these default flow rules are disabled (`fdb_def_rule_en` == 0)
with HW Steering flow engine (`dv_flow_en` == 2) only creation of
default jump rules was disabled. Also, necessary template table and
pattern/actions templates were created as well,
but they were never used.
SQ miss flow rules were still created.
This is a bug, because with `fdb_def_rule_en` == 0, application should
not expect any default E-Switch flow rules.

This patch fixes that by disabling all default E-Switch flow rules
creation and disabling creating templates for these flow rules,
when `fdb_def_rule_en` == 0.
If an application needs to run with these flow rules disabled,
and requires flow rules providing SQ miss flow rules functionality,
then application must explicitly create similar flow rules.

Fixes: 1939eb6 ("net/mlx5: support flow port action with HWS")
Cc: stable@dpdk.org

Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
  • Loading branch information
sodar authored and raslandarawsheh committed Jul 22, 2024
1 parent 9e34281 commit 60d122b
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 68 deletions.
142 changes: 78 additions & 64 deletions drivers/net/mlx5/mlx5_flow_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -10580,6 +10580,7 @@ flow_hw_create_ctrl_tables(struct rte_eth_dev *dev, struct rte_flow_error *error
struct mlx5_flow_hw_ctrl_fdb *hw_ctrl_fdb;
uint32_t xmeta = priv->sh->config.dv_xmeta_en;
uint32_t repr_matching = priv->sh->config.repr_matching;
uint32_t fdb_def_rule = priv->sh->config.fdb_def_rule;

MLX5_ASSERT(priv->hw_ctrl_fdb == NULL);
hw_ctrl_fdb = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*hw_ctrl_fdb), 0, SOCKET_ID_ANY);
Expand All @@ -10590,70 +10591,79 @@ flow_hw_create_ctrl_tables(struct rte_eth_dev *dev, struct rte_flow_error *error
goto err;
}
priv->hw_ctrl_fdb = hw_ctrl_fdb;
/* Create templates and table for default SQ miss flow rules - root table. */
hw_ctrl_fdb->esw_mgr_items_tmpl = flow_hw_create_ctrl_esw_mgr_pattern_template(dev, error);
if (!hw_ctrl_fdb->esw_mgr_items_tmpl) {
DRV_LOG(ERR, "port %u failed to create E-Switch Manager item"
" template for control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->regc_jump_actions_tmpl = flow_hw_create_ctrl_regc_jump_actions_template
(dev, error);
if (!hw_ctrl_fdb->regc_jump_actions_tmpl) {
DRV_LOG(ERR, "port %u failed to create REG_C set and jump action template"
" for control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->hw_esw_sq_miss_root_tbl = flow_hw_create_ctrl_sq_miss_root_table
(dev, hw_ctrl_fdb->esw_mgr_items_tmpl, hw_ctrl_fdb->regc_jump_actions_tmpl,
error);
if (!hw_ctrl_fdb->hw_esw_sq_miss_root_tbl) {
DRV_LOG(ERR, "port %u failed to create table for default sq miss (root table)"
" for control flows", dev->data->port_id);
goto err;
}
/* Create templates and table for default SQ miss flow rules - non-root table. */
hw_ctrl_fdb->regc_sq_items_tmpl = flow_hw_create_ctrl_regc_sq_pattern_template(dev, error);
if (!hw_ctrl_fdb->regc_sq_items_tmpl) {
DRV_LOG(ERR, "port %u failed to create SQ item template for"
" control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->port_actions_tmpl = flow_hw_create_ctrl_port_actions_template(dev, error);
if (!hw_ctrl_fdb->port_actions_tmpl) {
DRV_LOG(ERR, "port %u failed to create port action template"
" for control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->hw_esw_sq_miss_tbl = flow_hw_create_ctrl_sq_miss_table
(dev, hw_ctrl_fdb->regc_sq_items_tmpl, hw_ctrl_fdb->port_actions_tmpl,
error);
if (!hw_ctrl_fdb->hw_esw_sq_miss_tbl) {
DRV_LOG(ERR, "port %u failed to create table for default sq miss (non-root table)"
" for control flows", dev->data->port_id);
goto err;
}
/* Create templates and table for default FDB jump flow rules. */
hw_ctrl_fdb->port_items_tmpl = flow_hw_create_ctrl_port_pattern_template(dev, error);
if (!hw_ctrl_fdb->port_items_tmpl) {
DRV_LOG(ERR, "port %u failed to create SQ item template for"
" control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->jump_one_actions_tmpl = flow_hw_create_ctrl_jump_actions_template
(dev, MLX5_HW_LOWEST_USABLE_GROUP, error);
if (!hw_ctrl_fdb->jump_one_actions_tmpl) {
DRV_LOG(ERR, "port %u failed to create jump action template"
" for control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->hw_esw_zero_tbl = flow_hw_create_ctrl_jump_table
(dev, hw_ctrl_fdb->port_items_tmpl, hw_ctrl_fdb->jump_one_actions_tmpl,
error);
if (!hw_ctrl_fdb->hw_esw_zero_tbl) {
DRV_LOG(ERR, "port %u failed to create table for default jump to group 1"
" for control flows", dev->data->port_id);
goto err;
if (fdb_def_rule) {
/* Create templates and table for default SQ miss flow rules - root table. */
hw_ctrl_fdb->esw_mgr_items_tmpl =
flow_hw_create_ctrl_esw_mgr_pattern_template(dev, error);
if (!hw_ctrl_fdb->esw_mgr_items_tmpl) {
DRV_LOG(ERR, "port %u failed to create E-Switch Manager item"
" template for control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->regc_jump_actions_tmpl =
flow_hw_create_ctrl_regc_jump_actions_template(dev, error);
if (!hw_ctrl_fdb->regc_jump_actions_tmpl) {
DRV_LOG(ERR, "port %u failed to create REG_C set and jump action template"
" for control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->hw_esw_sq_miss_root_tbl =
flow_hw_create_ctrl_sq_miss_root_table
(dev, hw_ctrl_fdb->esw_mgr_items_tmpl,
hw_ctrl_fdb->regc_jump_actions_tmpl, error);
if (!hw_ctrl_fdb->hw_esw_sq_miss_root_tbl) {
DRV_LOG(ERR, "port %u failed to create table for default sq miss (root table)"
" for control flows", dev->data->port_id);
goto err;
}
/* Create templates and table for default SQ miss flow rules - non-root table. */
hw_ctrl_fdb->regc_sq_items_tmpl =
flow_hw_create_ctrl_regc_sq_pattern_template(dev, error);
if (!hw_ctrl_fdb->regc_sq_items_tmpl) {
DRV_LOG(ERR, "port %u failed to create SQ item template for"
" control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->port_actions_tmpl =
flow_hw_create_ctrl_port_actions_template(dev, error);
if (!hw_ctrl_fdb->port_actions_tmpl) {
DRV_LOG(ERR, "port %u failed to create port action template"
" for control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->hw_esw_sq_miss_tbl =
flow_hw_create_ctrl_sq_miss_table
(dev, hw_ctrl_fdb->regc_sq_items_tmpl,
hw_ctrl_fdb->port_actions_tmpl, error);
if (!hw_ctrl_fdb->hw_esw_sq_miss_tbl) {
DRV_LOG(ERR, "port %u failed to create table for default sq miss (non-root table)"
" for control flows", dev->data->port_id);
goto err;
}
/* Create templates and table for default FDB jump flow rules. */
hw_ctrl_fdb->port_items_tmpl =
flow_hw_create_ctrl_port_pattern_template(dev, error);
if (!hw_ctrl_fdb->port_items_tmpl) {
DRV_LOG(ERR, "port %u failed to create SQ item template for"
" control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->jump_one_actions_tmpl =
flow_hw_create_ctrl_jump_actions_template
(dev, MLX5_HW_LOWEST_USABLE_GROUP, error);
if (!hw_ctrl_fdb->jump_one_actions_tmpl) {
DRV_LOG(ERR, "port %u failed to create jump action template"
" for control flows", dev->data->port_id);
goto err;
}
hw_ctrl_fdb->hw_esw_zero_tbl = flow_hw_create_ctrl_jump_table
(dev, hw_ctrl_fdb->port_items_tmpl,
hw_ctrl_fdb->jump_one_actions_tmpl, error);
if (!hw_ctrl_fdb->hw_esw_zero_tbl) {
DRV_LOG(ERR, "port %u failed to create table for default jump to group 1"
" for control flows", dev->data->port_id);
goto err;
}
}
/* Create templates and table for default Tx metadata copy flow rule. */
if (!repr_matching && xmeta == MLX5_XMETA_MODE_META32_HWS) {
Expand Down Expand Up @@ -15383,6 +15393,8 @@ mlx5_flow_hw_esw_destroy_sq_miss_flow(struct rte_eth_dev *dev, uint32_t sqn)
}
proxy_dev = &rte_eth_devices[proxy_port_id];
proxy_priv = proxy_dev->data->dev_private;
/* FDB default flow rules must be enabled. */
MLX5_ASSERT(proxy_priv->sh->config.fdb_def_rule);
if (!proxy_priv->dr_ctx)
return 0;
if (!proxy_priv->hw_ctrl_fdb ||
Expand Down Expand Up @@ -15447,6 +15459,8 @@ mlx5_flow_hw_esw_create_default_jump_flow(struct rte_eth_dev *dev)
}
proxy_dev = &rte_eth_devices[proxy_port_id];
proxy_priv = proxy_dev->data->dev_private;
/* FDB default flow rules must be enabled. */
MLX5_ASSERT(proxy_priv->sh->config.fdb_def_rule);
if (!proxy_priv->dr_ctx) {
DRV_LOG(DEBUG, "Transfer proxy port (port %u) of port %u must be configured "
"for HWS to create default FDB jump rule. Default rule will "
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/mlx5/mlx5_trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -1504,7 +1504,9 @@ mlx5_traffic_enable_hws(struct rte_eth_dev *dev)
if (!txq)
continue;
queue = mlx5_txq_get_sqn(txq);
if ((priv->representor || priv->master) && config->dv_esw_en) {
if ((priv->representor || priv->master) &&
config->dv_esw_en &&
config->fdb_def_rule) {
if (mlx5_flow_hw_esw_create_sq_miss_flow(dev, queue, false)) {
mlx5_txq_release(dev, i);
goto error;
Expand Down
13 changes: 10 additions & 3 deletions drivers/net/mlx5/mlx5_txq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1363,11 +1363,18 @@ rte_pmd_mlx5_external_sq_enable(uint16_t port_id, uint32_t sq_num)
}
#ifdef HAVE_MLX5_HWS_SUPPORT
if (priv->sh->config.dv_flow_en == 2) {
if (mlx5_flow_hw_esw_create_sq_miss_flow(dev, sq_num, true))
return -rte_errno;
bool sq_miss_created = false;

if (priv->sh->config.fdb_def_rule) {
if (mlx5_flow_hw_esw_create_sq_miss_flow(dev, sq_num, true))
return -rte_errno;
sq_miss_created = true;
}

if (priv->sh->config.repr_matching &&
mlx5_flow_hw_tx_repr_matching_flow(dev, sq_num, true)) {
mlx5_flow_hw_esw_destroy_sq_miss_flow(dev, sq_num);
if (sq_miss_created)
mlx5_flow_hw_esw_destroy_sq_miss_flow(dev, sq_num);
return -rte_errno;
}
return 0;
Expand Down

0 comments on commit 60d122b

Please sign in to comment.