* [dpdk-dev] [PATCH v1 1/2] net/mlx5: fix RSS expansion for 'explicit' graph node
2021-09-05 9:35 [dpdk-dev] [PATCH v1 0/2] Fixes in the RSS expansion method Lior Margalit
@ 2021-09-05 9:35 ` Lior Margalit
2021-09-05 9:35 ` [dpdk-dev] [PATCH v1 2/2] net/mlx5: fix RSS expansion traversal over next nodes Lior Margalit
2021-09-12 9:29 ` [dpdk-dev] [PATCH v1 0/2] Fixes in the RSS expansion method Raslan Darawsheh
2 siblings, 0 replies; 4+ messages in thread
From: Lior Margalit @ 2021-09-05 9:35 UTC (permalink / raw)
To: Matan Azrad; +Cc: Lior Margalit, dev, stable
The RSS expansion algorithm is using a graph to find the possible
expansion paths. A graph node with the 'explicit' flag will be skipped,
if it is not found in the flow pattern.
The current implementation misses the case where the node with the
explicit flag is in the middle of the expanded path.
For example:
testpmd> flow create 0 ingress pattern eth / ipv6 / udp / vxlan / end
actions rss level 2 types tcp end / end
The VLAN node has the explicit flag, so it is currently included in the
expanded flow:
ETH IPV6 UDP VXLAN END
ETH IPV6 UDP VXLAN ETH VLAN IPV4 TCP END
ETH IPV6 UDP VXLAN ETH VLAN IPV6 TCP END
The fix is to skip the nodes with the explicit flag while iterating over
the possible expansion paths. Using the above example, the flows will be:
ETH IPV6 UDP VXLAN END
ETH IPV6 UDP VXLAN ETH IPV4 TCP END
ETH IPV6 UDP VXLAN ETH IPV6 TCP END
Fixes: 3f02c7ff6815 ("net/mlx5: fix RSS expansion for inner tunnel VLAN")
Cc: stable@dpdk.org
Signed-off-by: Lior Margalit <lmargalit@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
drivers/net/mlx5/mlx5_flow.c | 44 ++++++++++++++++++++++++------------
1 file changed, 29 insertions(+), 15 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 4762fa0f5f..6cf1bb810d 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -259,6 +259,26 @@ mlx5_flow_expand_rss_item_complete(const struct rte_flow_item *item)
return ret;
}
+static const int *
+mlx5_flow_expand_rss_skip_explicit(const struct mlx5_flow_expand_node graph[],
+ const int *next_node)
+{
+ const struct mlx5_flow_expand_node *node = NULL;
+ const int *next = next_node;
+
+ while (next && *next) {
+ /*
+ * Skip the nodes with the MLX5_EXPANSION_NODE_EXPLICIT
+ * flag set, because they were not found in the flow pattern.
+ */
+ node = &graph[*next];
+ if (!(node->node_flags & MLX5_EXPANSION_NODE_EXPLICIT))
+ break;
+ next = node->next;
+ }
+ return next;
+}
+
#define MLX5_RSS_EXP_ELT_N 16
/**
@@ -391,17 +411,8 @@ mlx5_flow_expand_rss(struct mlx5_flow_expand_rss *buf, size_t size,
}
}
memset(flow_items, 0, sizeof(flow_items));
- next_node = node->next;
- while (next_node) {
- /*
- * Skip the nodes with the MLX5_EXPANSION_NODE_EXPLICIT
- * flag set, because they were not found in the flow pattern.
- */
- node = &graph[*next_node];
- if (!(node->node_flags & MLX5_EXPANSION_NODE_EXPLICIT))
- break;
- next_node = node->next;
- }
+ next_node = mlx5_flow_expand_rss_skip_explicit(graph,
+ node->next);
stack[stack_pos] = next_node;
node = next_node ? &graph[*next_node] : NULL;
while (node) {
@@ -438,7 +449,8 @@ mlx5_flow_expand_rss(struct mlx5_flow_expand_rss *buf, size_t size,
/* Go deeper. */
if (!(node->node_flags & MLX5_EXPANSION_NODE_OPTIONAL) &&
node->next) {
- next_node = node->next;
+ next_node = mlx5_flow_expand_rss_skip_explicit(graph,
+ node->next);
if (stack_pos++ == MLX5_RSS_EXP_ELT_N) {
rte_errno = E2BIG;
return -rte_errno;
@@ -446,15 +458,17 @@ mlx5_flow_expand_rss(struct mlx5_flow_expand_rss *buf, size_t size,
stack[stack_pos] = next_node;
} else if (*(next_node + 1)) {
/* Follow up with the next possibility. */
- ++next_node;
+ next_node = mlx5_flow_expand_rss_skip_explicit(graph,
+ ++next_node);
} else {
/* Move to the next path. */
if (stack_pos)
next_node = stack[--stack_pos];
- next_node++;
+ next_node = mlx5_flow_expand_rss_skip_explicit(graph,
+ ++next_node);
stack[stack_pos] = next_node;
}
- node = *next_node ? &graph[*next_node] : NULL;
+ node = next_node && *next_node ? &graph[*next_node] : NULL;
};
return lsize;
}
--
2.25.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [dpdk-dev] [PATCH v1 2/2] net/mlx5: fix RSS expansion traversal over next nodes
2021-09-05 9:35 [dpdk-dev] [PATCH v1 0/2] Fixes in the RSS expansion method Lior Margalit
2021-09-05 9:35 ` [dpdk-dev] [PATCH v1 1/2] net/mlx5: fix RSS expansion for 'explicit' graph node Lior Margalit
@ 2021-09-05 9:35 ` Lior Margalit
2021-09-12 9:29 ` [dpdk-dev] [PATCH v1 0/2] Fixes in the RSS expansion method Raslan Darawsheh
2 siblings, 0 replies; 4+ messages in thread
From: Lior Margalit @ 2021-09-05 9:35 UTC (permalink / raw)
To: Matan Azrad; +Cc: Lior Margalit, dev, stable
The RSS expansion is based on DFS algorithm to traverse over the possible
expansion paths.
The current implementation breaks out, if it reaches the terminator of the
"next nodes" array, instead of going backwards to try the next path.
For example:
testpmd> flow create 0 ingress pattern eth / ipv6 / udp / vxlan / end
actions rss level 2 types tcp end / end
The paths found are:
ETH IPV6 UDP VXLAN END
ETH IPV6 UDP VXLAN ETH IPV4 TCP END
ETH IPV6 UDP VXLAN ETH IPV6 TCP END
The traversal stopped after getting to the terminator of the next nodes of
the ETH node. It missed the rest of the nodes in the next nodes array of
the VXLAN node.
The fix is to go backwards when reaching the terminator of the current
level and find if there is a "next node" to start traversing a new path.
Using the above example, the flows will be:
ETH IPV6 UDP VXLAN END
ETH IPV6 UDP VXLAN ETH IPV4 TCP END
ETH IPV6 UDP VXLAN ETH IPV6 TCP END
ETH IPV6 UDP VXLAN IPV4 TCP END
ETH IPV6 UDP VXLAN IPV6 TCP END
The traversal will find additional paths, because it traverses through all
the next nodes array of the VXLAN node.
Fixes: 4ed05fc ("ethdev: add flow API to expand RSS flows")
Cc: stable@dpdk.org
Signed-off-by: Lior Margalit <lmargalit@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
drivers/net/mlx5/mlx5_flow.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 6cf1bb810d..c914a7120c 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -460,12 +460,22 @@ mlx5_flow_expand_rss(struct mlx5_flow_expand_rss *buf, size_t size,
/* Follow up with the next possibility. */
next_node = mlx5_flow_expand_rss_skip_explicit(graph,
++next_node);
+ } else if (!stack_pos) {
+ /*
+ * Completing the traverse over the different paths.
+ * The next_node is advanced to the terminator.
+ */
+ ++next_node;
} else {
/* Move to the next path. */
- if (stack_pos)
+ while (stack_pos) {
next_node = stack[--stack_pos];
+ next_node++;
+ if (*next_node)
+ break;
+ }
next_node = mlx5_flow_expand_rss_skip_explicit(graph,
- ++next_node);
+ next_node);
stack[stack_pos] = next_node;
}
node = next_node && *next_node ? &graph[*next_node] : NULL;
--
2.25.1
^ permalink raw reply [flat|nested] 4+ messages in thread