Skip to content

Commit

Permalink
net/mlx5: add extended metadata mode for HWS
Browse files Browse the repository at this point in the history
The new mode 4 of devarg "dv_xmeta_en" is added for HWS only. In this
mode, the Rx / Tx metadata with 32b width copy between FDB and NIC is
supported.

The mark is only supported in NIC and there is no copy supported.

Signed-off-by: Bing Zhao <[email protected]>
Acked-by: Viacheslav Ovsiienko <[email protected]>
  • Loading branch information
zorrohahaha authored and raslandarawsheh committed Oct 26, 2022
1 parent 1939eb6 commit ddb68e4
Show file tree
Hide file tree
Showing 10 changed files with 877 additions and 85 deletions.
4 changes: 4 additions & 0 deletions doc/guides/nics/mlx5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,10 @@ for an additional list of options shared with other mlx5 drivers.
- 3, this engages tunnel offload mode. In E-Switch configuration, that
mode implicitly activates ``dv_xmeta_en=1``.

- 4, this mode is only supported in HWS (``dv_flow_en=2``).
The Rx/Tx metadata with 32b width copy between FDB and NIC is supported.
The mark is only supported in NIC and there is no copy supported.

+------+-----------+-----------+-------------+-------------+
| Mode | ``MARK`` | ``META`` | ``META`` Tx | FDB/Through |
+======+===========+===========+=============+=============+
Expand Down
1 change: 1 addition & 0 deletions doc/guides/rel_notes/release_22_11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ New Features
* **Updated NVIDIA mlx5 driver.**

* Added full support for queue-based async HW steering.
- Support of FDB.
- Support of modify fields.

* **Updated NXP dpaa2 driver.**
Expand Down
10 changes: 9 additions & 1 deletion drivers/net/mlx5/linux/mlx5_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -1567,6 +1567,15 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
#ifdef HAVE_MLX5_HWS_SUPPORT
if (priv->vport_meta_mask)
flow_hw_set_port_info(eth_dev);
if (priv->sh->config.dv_esw_en &&
priv->sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
priv->sh->config.dv_xmeta_en != MLX5_XMETA_MODE_META32_HWS) {
DRV_LOG(ERR,
"metadata mode %u is not supported in HWS eswitch mode",
priv->sh->config.dv_xmeta_en);
err = ENOTSUP;
goto error;
}
/* Only HWS requires this information. */
flow_hw_init_tags_set(eth_dev);
if (priv->sh->config.dv_esw_en &&
Expand All @@ -1582,7 +1591,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
goto error;
#endif
}
/* Port representor shares the same max priority with pf port. */
if (!priv->sh->flow_priority_check_flag) {
/* Supported Verbs flow priority number detection. */
err = mlx5_flow_discover_priorities(eth_dev);
Expand Down
7 changes: 6 additions & 1 deletion drivers/net/mlx5/mlx5.c
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,8 @@ mlx5_dev_args_check_handler(const char *key, const char *val, void *opaque)
if (tmp != MLX5_XMETA_MODE_LEGACY &&
tmp != MLX5_XMETA_MODE_META16 &&
tmp != MLX5_XMETA_MODE_META32 &&
tmp != MLX5_XMETA_MODE_MISS_INFO) {
tmp != MLX5_XMETA_MODE_MISS_INFO &&
tmp != MLX5_XMETA_MODE_META32_HWS) {
DRV_LOG(ERR, "Invalid extensive metadata parameter.");
rte_errno = EINVAL;
return -rte_errno;
Expand Down Expand Up @@ -2849,6 +2850,10 @@ mlx5_set_metadata_mask(struct rte_eth_dev *dev)
meta = UINT32_MAX;
mark = (reg_c0 >> rte_bsf32(reg_c0)) & MLX5_FLOW_MARK_MASK;
break;
case MLX5_XMETA_MODE_META32_HWS:
meta = UINT32_MAX;
mark = MLX5_FLOW_MARK_MASK;
break;
default:
meta = 0;
mark = 0;
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/mlx5/mlx5.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,8 @@ struct mlx5_sh_config {
uint32_t reclaim_mode:2; /* Memory reclaim mode. */
uint32_t dv_esw_en:1; /* Enable E-Switch DV flow. */
/* Enable DV flow. 1 means SW steering, 2 means HW steering. */
unsigned int dv_flow_en:2;
uint32_t dv_xmeta_en:2; /* Enable extensive flow metadata. */
uint32_t dv_flow_en:2; /* Enable DV flow. */
uint32_t dv_xmeta_en:3; /* Enable extensive flow metadata. */
uint32_t dv_miss_info:1; /* Restore packet after partial hw miss. */
uint32_t l3_vxlan_en:1; /* Enable L3 VXLAN flow creation. */
uint32_t vf_nl_en:1; /* Enable Netlink requests in VF mode. */
Expand All @@ -317,7 +317,6 @@ struct mlx5_sh_config {
uint32_t fdb_def_rule:1; /* Create FDB default jump rule */
};


/* Structure for VF VLAN workaround. */
struct mlx5_vf_vlan {
uint32_t tag:12;
Expand Down Expand Up @@ -1290,12 +1289,12 @@ struct mlx5_dev_ctx_shared {
struct mlx5_lb_ctx self_lb; /* QP to enable self loopback for Devx. */
unsigned int flow_max_priority;
enum modify_reg flow_mreg_c[MLX5_MREG_C_NUM];
/* Availability of mreg_c's. */
void *devx_channel_lwm;
struct rte_intr_handle *intr_handle_lwm;
pthread_mutex_t lwm_config_lock;
uint32_t host_shaper_rate:8;
uint32_t lwm_triggered:1;
/* Availability of mreg_c's. */
struct mlx5_dev_shared_port port[]; /* per device port data array. */
};

Expand Down Expand Up @@ -1521,6 +1520,7 @@ struct mlx5_priv {
struct rte_flow_template_table *hw_esw_sq_miss_root_tbl;
struct rte_flow_template_table *hw_esw_sq_miss_tbl;
struct rte_flow_template_table *hw_esw_zero_tbl;
struct rte_flow_template_table *hw_tx_meta_cpy_tbl;
struct mlx5_indexed_pool *flows[MLX5_FLOW_TYPE_MAXI];
/* RTE Flow rules. */
uint32_t ctrl_flows; /* Control flow rules. */
Expand Down
8 changes: 7 additions & 1 deletion drivers/net/mlx5/mlx5_flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,8 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
return REG_C_0;
case MLX5_XMETA_MODE_META32:
return REG_C_1;
case MLX5_XMETA_MODE_META32_HWS:
return REG_C_1;
}
break;
case MLX5_METADATA_TX:
Expand All @@ -1117,11 +1119,14 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
return REG_C_0;
case MLX5_XMETA_MODE_META32:
return REG_C_1;
case MLX5_XMETA_MODE_META32_HWS:
return REG_C_1;
}
break;
case MLX5_FLOW_MARK:
switch (config->dv_xmeta_en) {
case MLX5_XMETA_MODE_LEGACY:
case MLX5_XMETA_MODE_META32_HWS:
return REG_NON;
case MLX5_XMETA_MODE_META16:
return REG_C_1;
Expand Down Expand Up @@ -4440,7 +4445,8 @@ static bool flow_check_modify_action_type(struct rte_eth_dev *dev,
return true;
case RTE_FLOW_ACTION_TYPE_FLAG:
case RTE_FLOW_ACTION_TYPE_MARK:
if (priv->sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY)
if (priv->sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
priv->sh->config.dv_xmeta_en != MLX5_XMETA_MODE_META32_HWS)
return true;
else
return false;
Expand Down
14 changes: 14 additions & 0 deletions drivers/net/mlx5/mlx5_flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ enum mlx5_rte_flow_action_type {
MLX5_RTE_FLOW_ACTION_TYPE_RSS,
};

/* Private (internal) Field IDs for MODIFY_FIELD action. */
enum mlx5_rte_flow_field_id {
MLX5_RTE_FLOW_FIELD_END = INT_MIN,
MLX5_RTE_FLOW_FIELD_META_REG,
};

#define MLX5_INDIRECT_ACTION_TYPE_OFFSET 30

enum {
Expand Down Expand Up @@ -1181,6 +1187,7 @@ struct rte_flow_actions_template {
struct rte_flow_action *masks; /* Cached action masks.*/
uint16_t mhdr_off; /* Offset of DR modify header action. */
uint32_t refcnt; /* Reference counter. */
uint16_t rx_cpy_pos; /* Action position of Rx metadata to be copied. */
};

/* Jump action struct. */
Expand Down Expand Up @@ -1257,6 +1264,11 @@ struct mlx5_flow_group {
#define MLX5_HW_TBL_MAX_ITEM_TEMPLATE 2
#define MLX5_HW_TBL_MAX_ACTION_TEMPLATE 32

struct mlx5_flow_template_table_cfg {
struct rte_flow_template_table_attr attr; /* Table attributes passed through flow API. */
bool external; /* True if created by flow API, false if table is internal to PMD. */
};

struct rte_flow_template_table {
LIST_ENTRY(rte_flow_template_table) next;
struct mlx5_flow_group *grp; /* The group rte_flow_template_table uses. */
Expand All @@ -1266,6 +1278,7 @@ struct rte_flow_template_table {
/* Action templates bind to the table. */
struct mlx5_hw_action_template ats[MLX5_HW_TBL_MAX_ACTION_TEMPLATE];
struct mlx5_indexed_pool *flow; /* The table's flow ipool. */
struct mlx5_flow_template_table_cfg cfg;
uint32_t type; /* Flow table type RX/TX/FDB. */
uint8_t nb_item_templates; /* Item template number. */
uint8_t nb_action_templates; /* Action template number. */
Expand Down Expand Up @@ -2378,4 +2391,5 @@ int mlx5_flow_hw_esw_create_mgr_sq_miss_flow(struct rte_eth_dev *dev);
int mlx5_flow_hw_esw_create_sq_miss_flow(struct rte_eth_dev *dev,
uint32_t txq);
int mlx5_flow_hw_esw_create_default_jump_flow(struct rte_eth_dev *dev);
int mlx5_flow_hw_create_tx_default_mreg_copy_flow(struct rte_eth_dev *dev);
#endif /* RTE_PMD_MLX5_FLOW_H_ */
43 changes: 39 additions & 4 deletions drivers/net/mlx5/mlx5_flow_dv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1754,7 +1754,8 @@ mlx5_flow_field_id_to_modify_info
int reg;

if (priv->sh->config.dv_flow_en == 2)
reg = REG_C_1;
reg = flow_hw_get_reg_id(RTE_FLOW_ITEM_TYPE_TAG,
data->level);
else
reg = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG,
data->level, error);
Expand Down Expand Up @@ -1833,6 +1834,24 @@ mlx5_flow_field_id_to_modify_info
else
info[idx].offset = off_be;
break;
case MLX5_RTE_FLOW_FIELD_META_REG:
{
uint32_t meta_mask = priv->sh->dv_meta_mask;
uint32_t meta_count = __builtin_popcount(meta_mask);
uint32_t reg = data->level;

RTE_SET_USED(meta_count);
MLX5_ASSERT(data->offset + width <= meta_count);
MLX5_ASSERT(reg != REG_NON);
MLX5_ASSERT(reg < RTE_DIM(reg_to_field));
info[idx] = (struct field_modify_info){4, 0, reg_to_field[reg]};
if (mask)
mask[idx] = flow_modify_info_mask_32_masked
(width, data->offset, meta_mask);
else
info[idx].offset = data->offset;
}
break;
case RTE_FLOW_FIELD_POINTER:
case RTE_FLOW_FIELD_VALUE:
default:
Expand Down Expand Up @@ -9796,7 +9815,19 @@ flow_dv_translate_item_meta(struct rte_eth_dev *dev,
mask = meta_m->data;
if (key_type == MLX5_SET_MATCHER_HS_M)
mask = value;
reg = flow_dv_get_metadata_reg(dev, attr, NULL);
/*
* In the current implementation, REG_B cannot be used to match.
* Force to use REG_C_1 in HWS root table as other tables.
* This map may change.
* NIC: modify - REG_B to be present in SW
* match - REG_C_1 when copied from FDB, different from SWS
* FDB: modify - REG_C_1 in Xmeta mode, REG_NON in legacy mode
* match - REG_C_1 in FDB
*/
if (!!(key_type & MLX5_SET_MATCHER_SW))
reg = flow_dv_get_metadata_reg(dev, attr, NULL);
else
reg = flow_hw_get_reg_id(RTE_FLOW_ITEM_TYPE_META, 0);
if (reg < 0)
return;
MLX5_ASSERT(reg != REG_NON);
Expand Down Expand Up @@ -9896,7 +9927,10 @@ flow_dv_translate_item_tag(struct rte_eth_dev *dev, void *key,
/* When set mask, the index should be from spec. */
index = tag_vv ? tag_vv->index : tag_v->index;
/* Get the metadata register index for the tag. */
reg = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, index, NULL);
if (!!(key_type & MLX5_SET_MATCHER_SW))
reg = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, index, NULL);
else
reg = flow_hw_get_reg_id(RTE_FLOW_ITEM_TYPE_TAG, index);
MLX5_ASSERT(reg > 0);
flow_dv_match_meta_reg(key, reg, tag_v->data, tag_m->data);
}
Expand Down Expand Up @@ -13465,7 +13499,8 @@ flow_dv_translate_items_sws(struct rte_eth_dev *dev,
*/
if (!(wks.item_flags & MLX5_FLOW_ITEM_PORT_ID) &&
!(wks.item_flags & MLX5_FLOW_ITEM_REPRESENTED_PORT) && priv->sh->esw_mode &&
!(attr->egress && !attr->transfer)) {
!(attr->egress && !attr->transfer) &&
attr->group != MLX5_FLOW_MREG_CP_TABLE_GROUP) {
if (flow_dv_translate_item_port_id_all(dev, match_mask,
match_value, NULL, attr))
return -rte_errno;
Expand Down
Loading

0 comments on commit ddb68e4

Please sign in to comment.