[12/27] net/mlx5: support caching queue action

Message ID 20220923144334.27736-13-suanmingm@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series net/mlx5: HW steering PMD update |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Suanming Mou Sept. 23, 2022, 2:43 p.m. UTC
  If the port is stopped, the Rx queue data will also be destroyed. At that
time, create table with RSS action would be failed due to lack of Rx queue
data.

This commit adds the cache of queue create operation while port stopped.
In case  port is stopped, add tables to the ongoing list first, then do
action translate only when port starts.

Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
---
 drivers/net/mlx5/mlx5.h         |  2 +
 drivers/net/mlx5/mlx5_flow.h    |  2 +
 drivers/net/mlx5/mlx5_flow_hw.c | 95 +++++++++++++++++++++++++++++----
 drivers/net/mlx5/mlx5_trigger.c |  8 +++
 4 files changed, 97 insertions(+), 10 deletions(-)
  

Patch

diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 8d82c68569..be60038810 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -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
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index cdea4076d8..746cf439fc 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -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_ */
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 8891f4a4e3..fe40b02c49 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -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);
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 9e458356a0..ab2b83a870 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -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",