[dpdk-dev] [RFC] net/mlx5: enlarge maximum flow priority

Dong Zhou dongzhou at nvidia.com
Mon Dec 14 15:16:47 CET 2020


Currently, the maximum flow priority to user is 4, PMD will
manage 3 sub-priorities per user priority according to L2, L3
and L4. This count of priority is not enough if user want to
do some flow match by priorities, such as LPM, for one IPV4
address, we need 32 priorities for each bit of 32 mask len.

This RFC introduces new priority mode by using devargs
"flow_priority_mode=0", the maximum priority to user can reach
16K. User can specify the priority of flow that PMD will not
adjust it.

Signed-off-by: Dong Zhou <dongzhou at nvidia.com>
---
 drivers/net/mlx5/mlx5.c            |  6 ++++
 drivers/net/mlx5/mlx5.h            |  6 ++++
 drivers/net/mlx5/mlx5_flow.c       | 56 +++++++++++++++++++++++++++++++++++++-
 drivers/net/mlx5/mlx5_flow.h       | 14 ++++++++++
 drivers/net/mlx5/mlx5_flow_dv.c    |  9 ++----
 drivers/net/mlx5/mlx5_flow_verbs.c |  7 ++++-
 6 files changed, 90 insertions(+), 8 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 52a8a25..50249a9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -169,6 +169,9 @@
 /* Flow memory reclaim mode. */
 #define MLX5_RECLAIM_MEM "reclaim_mem_mode"
 
+/* Flow priority mode. */
+#define MLX5_FLOW_PRIORITY_MODE "flow_priority_mode"
+
 /* The default memory allocator used in PMD. */
 #define MLX5_SYS_MEM_EN "sys_mem_en"
 /* Decap will be used or not. */
@@ -1580,6 +1583,8 @@ struct mlx5_dev_ctx_shared *
 		config->sys_mem_en = !!tmp;
 	} else if (strcmp(MLX5_DECAP_EN, key) == 0) {
 		config->decap_en = !!tmp;
+	} else if (strcmp(MLX5_FLOW_PRIORITY_MODE, key) == 0) {
+		config->flow_priority_mode = !!tmp;
 	} else {
 		DRV_LOG(WARNING, "%s: unknown parameter", key);
 		rte_errno = EINVAL;
@@ -1640,6 +1645,7 @@ struct mlx5_dev_ctx_shared *
 		MLX5_RECLAIM_MEM,
 		MLX5_SYS_MEM_EN,
 		MLX5_DECAP_EN,
+		MLX5_FLOW_PRIORITY_MODE,
 		NULL,
 	};
 	struct rte_kvargs *kvlist;
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 121d726..499467d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -227,6 +227,12 @@ struct mlx5_dev_config {
 	unsigned int sys_mem_en:1; /* The default memory allocator. */
 	unsigned int decap_en:1; /* Whether decap will be used or not. */
 	unsigned int dv_miss_info:1; /* restore packet after partial hw miss */
+	unsigned int flow_priority_mode:1;
+	/* 0: the pmd will not adjust priority from user, the amount of
+	 *  priorities can reach 64K
+	 *  1: the pmd will manage 3 sub-priorities per user priority
+	 *  according to L2,L3 and L4.
+	 */
 	struct {
 		unsigned int enabled:1; /* Whether MPRQ is enabled. */
 		unsigned int stride_num_n; /* Number of strides. */
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 82e24d7..f967616 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -860,6 +860,60 @@ struct mlx5_flow_tunnel_info {
 }
 
 /**
+ * Get the max priority
+ *
+ * @param[in] dev
+ *   Pointer to the Ethernet device structure.
+ * @param[in] attributes
+ *   Pointer to device flow rule attributes.
+ *
+ * @return
+ *   The value of max priority of the flow .
+ */
+uint32_t
+mlx5_get_max_priority(struct rte_eth_dev *dev,
+			  const struct rte_flow_attr *attributes)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+
+	if (!attributes->group || priv->config.flow_priority_mode)
+		return priv->config.flow_prio - 1;
+	return MLX5_NON_ROOT_FLOW_MAX_PRIO;
+}
+/**
+ * Calculate matcher priority of the flow
+ *
+ * @param[in] dev
+ *   Pointer to the Ethernet device structure.
+ * @param[in] attributes
+ *   Pointer to device flow rule attributes.
+ * @param[in] actions
+ *   Pointer to the list of actions.
+ * @return
+ *   The matcher priority of the flow .
+ */
+uint16_t
+mlx5_get_matcher_priority(struct rte_eth_dev *dev,
+			  const struct rte_flow_attr *attr,
+			  const struct rte_flow_action actions[],
+			  uint32_t subpriority)
+{
+	uint16_t priority = (uint16_t)attr->priority;
+	struct mlx5_priv *priv = dev->data->dev_private;
+
+	if (attr->priority == MLX5_FLOW_PRIO_RSVD)
+		priority = mlx5_get_max_priority(dev, attr);
+	if (priv->config.flow_priority_mode)
+		return mlx5_flow_adjust_priority(dev, priority, subpriority);
+	priority = MLX5_LACP_PRIO_OFFSET + priority * 3;
+	/*For default or rss flows,PMD will adjuest priority with sub-priority*/
+	if (attr->priority == MLX5_FLOW_PRIO_RSVD ||
+		flow_get_rss_action(actions) != NULL)
+		priority += subpriority;
+	return priority;
+}
+
+/**
  * Verify the @p item specifications (spec, last, mask) are compatible with the
  * NIC capabilities.
  *
@@ -3146,7 +3200,7 @@ struct mlx5_flow_tunnel_info {
  * @return
  *   Pointer to the RSS action if exist, else return NULL.
  */
-static const struct rte_flow_action_rss*
+const struct rte_flow_action_rss*
 flow_get_rss_action(const struct rte_flow_action actions[])
 {
 	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index d85dd19..eaa4b77 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -269,6 +269,12 @@ enum mlx5_feature_name {
 /* Priority reserved for default flows. */
 #define MLX5_FLOW_PRIO_RSVD ((uint32_t)-1)
 
+/*reserve priority 0 for LACP protocol packet*/
+#define MLX5_LACP_PRIO_OFFSET		(1)
+
+/* Max priority for non-root flows 16k. */
+#define MLX5_NON_ROOT_FLOW_MAX_PRIO	(16 * 1024)
+
 /*
  * Number of sub priorities.
  * For each kind of pattern matching i.e. L2, L3, L4 to have a correct
@@ -1286,6 +1292,14 @@ uint64_t mlx5_flow_hashfields_adjust(struct mlx5_flow_rss_desc *rss_desc,
 int mlx5_flow_discover_priorities(struct rte_eth_dev *dev);
 uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
 				   uint32_t subpriority);
+uint32_t mlx5_get_max_priority(struct rte_eth_dev *dev,
+					const struct rte_flow_attr *attributes);
+uint16_t mlx5_get_matcher_priority(struct rte_eth_dev *dev,
+				     const struct rte_flow_attr *attr,
+				     const struct rte_flow_action actions[],
+				     uint32_t subpriority);
+const struct rte_flow_action_rss*
+flow_get_rss_action(const struct rte_flow_action actions[]);
 int mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
 				     enum mlx5_feature_name feature,
 				     uint32_t id,
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index c317376..66d4d3a 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -5131,7 +5131,7 @@ struct mlx5_hlist_entry *
 			    struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	uint32_t priority_max = priv->config.flow_prio - 1;
+	uint32_t priority_max = mlx5_get_max_priority(dev, attributes);
 	int ret = 0;
 
 #ifndef HAVE_MLX5DV_DR
@@ -9641,7 +9641,6 @@ struct mlx5_cache_entry *
 	uint64_t item_flags = 0;
 	uint64_t last_item = 0;
 	uint64_t action_flags = 0;
-	uint64_t priority = attr->priority;
 	struct mlx5_flow_dv_matcher matcher = {
 		.mask = {
 			.size = sizeof(matcher.mask.buf) -
@@ -9712,8 +9711,6 @@ struct mlx5_cache_entry *
 	dev_flow->dv.group = table;
 	if (attr->transfer)
 		mhdr_res->ft_type = MLX5DV_FLOW_TABLE_TYPE_FDB;
-	if (priority == MLX5_FLOW_PRIO_RSVD)
-		priority = dev_conf->flow_prio - 1;
 	/* number of actions must be set to 0 in case of dirty stack. */
 	mhdr_res->actions_num = 0;
 	if (is_flow_tunnel_match_rule(dev, attr, items, actions)) {
@@ -10567,8 +10564,8 @@ struct mlx5_cache_entry *
 	/* Register matcher. */
 	matcher.crc = rte_raw_cksum((const void *)matcher.mask.buf,
 				    matcher.mask.size);
-	matcher.priority = mlx5_flow_adjust_priority(dev, priority,
-						     matcher.priority);
+	matcher.priority = mlx5_get_matcher_priority(dev, attr, actions,
+					matcher.priority);
 	/* reserved field no needs to be set to 0 here. */
 	tbl_key.domain = attr->transfer;
 	tbl_key.direction = attr->egress;
diff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c
index 59291fb..4ba9cd2 100644
--- a/drivers/net/mlx5/mlx5_flow_verbs.c
+++ b/drivers/net/mlx5/mlx5_flow_verbs.c
@@ -89,6 +89,10 @@
 		claim_zero(mlx5_glue->destroy_flow(flow));
 		priority = vprio[i];
 	}
+	if (priv->config.flow_priority_mode == 0) {
+		priority = (priority - MLX5_LACP_PRIO_OFFSET) / 3;
+		goto end;
+	}
 	switch (priority) {
 	case 8:
 		priority = RTE_DIM(priority_map_3);
@@ -103,7 +107,8 @@
 			dev->data->port_id, priority);
 		return -rte_errno;
 	}
-	DRV_LOG(INFO, "port %u flow maximum priority: %d",
+end:
+	DRV_LOG(INFO, "port %u flow maximum priority: %d for root table",
 		dev->data->port_id, priority);
 	return priority;
 }
-- 
1.8.3.1



More information about the dev mailing list