@@ -1643,6 +1643,8 @@ struct mlx5_priv {
struct mlx5dr_action *hw_drop[2];
/* HW steering global tag action. */
struct mlx5dr_action *hw_tag[2];
+ /* HW steering create ongoing rte flow table list header. */
+ LIST_HEAD(flow_hw_tbl_ongo, rte_flow_template_table) flow_hw_tbl_ongo;
struct mlx5_indexed_pool *acts_ipool; /* Action data indexed pool. */
struct mlx5_hws_cnt_pool *hws_cpool; /* HW steering's counter pool. */
#endif
@@ -2398,4 +2398,6 @@ int mlx5_flow_pattern_validate(struct rte_eth_dev *dev,
const struct rte_flow_pattern_template_attr *attr,
const struct rte_flow_item items[],
struct rte_flow_error *error);
+int flow_hw_table_update(struct rte_eth_dev *dev,
+ struct rte_flow_error *error);
#endif /* RTE_PMD_MLX5_FLOW_H_ */
@@ -992,11 +992,11 @@ flow_hw_cnt_compile(struct rte_eth_dev *dev, uint32_t start_pos,
* Table on success, NULL otherwise and rte_errno is set.
*/
static int
-flow_hw_actions_translate(struct rte_eth_dev *dev,
- const struct mlx5_flow_template_table_cfg *cfg,
- struct mlx5_hw_actions *acts,
- struct rte_flow_actions_template *at,
- struct rte_flow_error *error)
+__flow_hw_actions_translate(struct rte_eth_dev *dev,
+ const struct mlx5_flow_template_table_cfg *cfg,
+ struct mlx5_hw_actions *acts,
+ struct rte_flow_actions_template *at,
+ struct rte_flow_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
const struct rte_flow_template_table_attr *table_attr = &cfg->attr;
@@ -1309,6 +1309,40 @@ flow_hw_actions_translate(struct rte_eth_dev *dev,
"fail to create rte table");
}
+/**
+ * Translate rte_flow actions to DR action.
+ *
+ * @param[in] dev
+ * Pointer to the rte_eth_dev structure.
+ * @param[in] tbl
+ * Pointer to the flow template table.
+ * @param[out] error
+ * Pointer to error structure.
+ *
+ * @return
+ * 0 on success, negative value otherwise and rte_errno is set.
+ */
+static int
+flow_hw_actions_translate(struct rte_eth_dev *dev,
+ struct rte_flow_template_table *tbl,
+ struct rte_flow_error *error)
+{
+ uint32_t i;
+
+ for (i = 0; i < tbl->nb_action_templates; i++) {
+ if (__flow_hw_actions_translate(dev, &tbl->cfg,
+ &tbl->ats[i].acts,
+ tbl->ats[i].action_template,
+ error))
+ goto err;
+ }
+ return 0;
+err:
+ while (i--)
+ __flow_hw_action_template_destroy(dev, &tbl->ats[i].acts);
+ return -1;
+}
+
/**
* Get shared indirect action.
*
@@ -1837,6 +1871,10 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
uint32_t acts_num, flow_idx;
int ret;
+ if (unlikely((!dev->data->dev_started))) {
+ rte_errno = EINVAL;
+ goto error;
+ }
if (unlikely(!priv->hw_q[queue].job_idx)) {
rte_errno = ENOMEM;
goto error;
@@ -2231,6 +2269,7 @@ flow_hw_table_create(struct rte_eth_dev *dev,
struct mlx5_list_entry *ge;
uint32_t i, max_tpl = MLX5_HW_TBL_MAX_ITEM_TEMPLATE;
uint32_t nb_flows = rte_align32pow2(attr->nb_flows);
+ bool port_started = !!dev->data->dev_started;
int err;
/* HWS layer accepts only 1 item template with root table. */
@@ -2295,21 +2334,26 @@ flow_hw_table_create(struct rte_eth_dev *dev,
rte_errno = EINVAL;
goto at_error;
}
+ tbl->ats[i].action_template = action_templates[i];
LIST_INIT(&tbl->ats[i].acts.act_list);
- err = flow_hw_actions_translate(dev, &tbl->cfg,
- &tbl->ats[i].acts,
- action_templates[i], error);
+ if (!port_started)
+ continue;
+ err = __flow_hw_actions_translate(dev, &tbl->cfg,
+ &tbl->ats[i].acts,
+ action_templates[i], error);
if (err) {
i++;
goto at_error;
}
- tbl->ats[i].action_template = action_templates[i];
}
tbl->nb_action_templates = nb_action_templates;
tbl->type = attr->flow_attr.transfer ? MLX5DR_TABLE_TYPE_FDB :
(attr->flow_attr.egress ? MLX5DR_TABLE_TYPE_NIC_TX :
MLX5DR_TABLE_TYPE_NIC_RX);
- LIST_INSERT_HEAD(&priv->flow_hw_tbl, tbl, next);
+ if (port_started)
+ LIST_INSERT_HEAD(&priv->flow_hw_tbl, tbl, next);
+ else
+ LIST_INSERT_HEAD(&priv->flow_hw_tbl_ongo, tbl, next);
return tbl;
at_error:
while (i--) {
@@ -2339,6 +2383,33 @@ flow_hw_table_create(struct rte_eth_dev *dev,
return NULL;
}
+/**
+ * Update flow template table.
+ *
+ * @param[in] dev
+ * Pointer to the rte_eth_dev structure.
+ * @param[out] error
+ * Pointer to error structure.
+ *
+ * @return
+ * 0 on success, negative value otherwise and rte_errno is set.
+ */
+int
+flow_hw_table_update(struct rte_eth_dev *dev,
+ struct rte_flow_error *error)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct rte_flow_template_table *tbl;
+
+ while ((tbl = LIST_FIRST(&priv->flow_hw_tbl_ongo)) != NULL) {
+ if (flow_hw_actions_translate(dev, tbl, error))
+ return -1;
+ LIST_REMOVE(tbl, next);
+ LIST_INSERT_HEAD(&priv->flow_hw_tbl, tbl, next);
+ }
+ return 0;
+}
+
/**
* Translates group index specified by the user in @p attr to internal
* group index.
@@ -4440,6 +4511,10 @@ flow_hw_resource_release(struct rte_eth_dev *dev)
if (!priv->dr_ctx)
return;
flow_hw_flush_all_ctrl_flows(dev);
+ while (!LIST_EMPTY(&priv->flow_hw_tbl_ongo)) {
+ tbl = LIST_FIRST(&priv->flow_hw_tbl_ongo);
+ flow_hw_table_destroy(dev, tbl, NULL);
+ }
while (!LIST_EMPTY(&priv->flow_hw_tbl)) {
tbl = LIST_FIRST(&priv->flow_hw_tbl);
flow_hw_table_destroy(dev, tbl, NULL);
@@ -1170,6 +1170,14 @@ mlx5_dev_start(struct rte_eth_dev *dev)
dev->data->port_id, rte_strerror(rte_errno));
goto error;
}
+ if (priv->sh->config.dv_flow_en == 2) {
+ ret = flow_hw_table_update(dev, NULL);
+ if (ret) {
+ DRV_LOG(ERR, "port %u failed to update HWS tables",
+ dev->data->port_id);
+ goto error;
+ }
+ }
ret = mlx5_traffic_enable(dev);
if (ret) {
DRV_LOG(ERR, "port %u failed to set defaults flows",