Skip to content

Commit 906154c

Browse files
ddvladkuba-moo
authored andcommitted
net/mlx5: HWS, Generalize complex matchers
The existing solution of complex matchers splits the match parameters across two, and exactly two, matchers. For some rather extreme cases (e.g. IPv6-in-IPv6 tunnels), even two matchers are not enough. Generalize complex matchers to up to 4 submatchers, and allow easy extension to more if needed. This resulted in rewriting a large part of the high-level complex matchers logic, but the original concepts were rock solid and still hold. Key characteristics of the new implementation: * Rework complex matchers to include multiple submatchers. All submatchers but the first are isolated, in keeping with the existing paradigm of handing off to specialized matchers that are not otherwise reachable by regular rules. * Similarly, rework complex rules to allow splitting them into more than two simple rules. Rules continue to be refcounted to allow for multiple complex rules matching on identical parts of the match params. * Rely on the match tag, as opposed to the entire match_param, to hash subrules. This results in lower memory usage. * Prefer to split the original user-supplied match parameters rather than the internal field descriptors. This avoids the awkward transition back and forth between the two formats. * Allow splitting multi-dword fields across matchers. The only restrictions that the new implementation impose are: a) any fragment of an IP address must be accompanied by a match on the IP version; and b) a single lower dword of an IPv6 address cannot be present in a submatcher as it would be interpreted as an IPv4 address. * Employ a greedy algorithm to split the match params, as opposed to complete search. The results are not optimal, but the algorithm is now linear compared to exponential. Consequently, we see complex matcher creation time drops two orders of magnitude in our tests. Signed-off-by: Vlad Dogaru <vdogaru@nvidia.com> Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com> Reviewed-by: Mark Bloch <mbloch@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/1759094723-843774-2-git-send-email-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent fd8c821 commit 906154c

6 files changed

Lines changed: 836 additions & 1199 deletions

File tree

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ static void hws_bwc_matcher_init_attr(struct mlx5hws_bwc_matcher *bwc_matcher,
5151
u8 size_log_rx, u8 size_log_tx,
5252
struct mlx5hws_matcher_attr *attr)
5353
{
54-
struct mlx5hws_bwc_matcher *first_matcher =
55-
bwc_matcher->complex_first_bwc_matcher;
56-
5754
memset(attr, 0, sizeof(*attr));
5855

5956
attr->priority = priority;
@@ -66,9 +63,6 @@ static void hws_bwc_matcher_init_attr(struct mlx5hws_bwc_matcher *bwc_matcher,
6663
attr->size[MLX5HWS_MATCHER_SIZE_TYPE_TX].rule.num_log = size_log_tx;
6764
attr->resizable = true;
6865
attr->max_num_of_at_attach = MLX5HWS_BWC_MATCHER_ATTACH_AT_NUM;
69-
70-
attr->isolated_matcher_end_ft_id =
71-
first_matcher ? first_matcher->matcher->end_ft_id : 0;
7266
}
7367

7468
static int
@@ -171,10 +165,16 @@ hws_bwc_matcher_move_all_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
171165

172166
static int hws_bwc_matcher_move_all(struct mlx5hws_bwc_matcher *bwc_matcher)
173167
{
174-
if (!bwc_matcher->complex)
168+
switch (bwc_matcher->matcher_type) {
169+
case MLX5HWS_BWC_MATCHER_SIMPLE:
175170
return hws_bwc_matcher_move_all_simple(bwc_matcher);
176-
177-
return mlx5hws_bwc_matcher_move_all_complex(bwc_matcher);
171+
case MLX5HWS_BWC_MATCHER_COMPLEX_FIRST:
172+
return mlx5hws_bwc_matcher_complex_move_first(bwc_matcher);
173+
case MLX5HWS_BWC_MATCHER_COMPLEX_SUBMATCHER:
174+
return mlx5hws_bwc_matcher_complex_move(bwc_matcher);
175+
default:
176+
return -EINVAL;
177+
}
178178
}
179179

180180
static int hws_bwc_matcher_move(struct mlx5hws_bwc_matcher *bwc_matcher)
@@ -249,6 +249,7 @@ int mlx5hws_bwc_matcher_create_simple(struct mlx5hws_bwc_matcher *bwc_matcher,
249249
bwc_matcher->tx_size.size_log,
250250
&attr);
251251

252+
bwc_matcher->matcher_type = MLX5HWS_BWC_MATCHER_SIMPLE;
252253
bwc_matcher->priority = priority;
253254

254255
bwc_matcher->size_of_at_array = MLX5HWS_BWC_MATCHER_ATTACH_AT_NUM;
@@ -393,7 +394,7 @@ int mlx5hws_bwc_matcher_destroy(struct mlx5hws_bwc_matcher *bwc_matcher)
393394
"BWC matcher destroy: matcher still has %u RX and %u TX rules\n",
394395
rx_rules, tx_rules);
395396

396-
if (bwc_matcher->complex)
397+
if (bwc_matcher->matcher_type == MLX5HWS_BWC_MATCHER_COMPLEX_FIRST)
397398
mlx5hws_bwc_matcher_destroy_complex(bwc_matcher);
398399
else
399400
mlx5hws_bwc_matcher_destroy_simple(bwc_matcher);
@@ -651,7 +652,8 @@ int mlx5hws_bwc_rule_destroy_simple(struct mlx5hws_bwc_rule *bwc_rule)
651652

652653
int mlx5hws_bwc_rule_destroy(struct mlx5hws_bwc_rule *bwc_rule)
653654
{
654-
bool is_complex = !!bwc_rule->bwc_matcher->complex;
655+
bool is_complex = bwc_rule->bwc_matcher->matcher_type ==
656+
MLX5HWS_BWC_MATCHER_COMPLEX_FIRST;
655657
int ret = 0;
656658

657659
if (is_complex)
@@ -1147,7 +1149,7 @@ mlx5hws_bwc_rule_create(struct mlx5hws_bwc_matcher *bwc_matcher,
11471149

11481150
bwc_queue_idx = hws_bwc_gen_queue_idx(ctx);
11491151

1150-
if (bwc_matcher->complex)
1152+
if (bwc_matcher->matcher_type == MLX5HWS_BWC_MATCHER_COMPLEX_FIRST)
11511153
ret = mlx5hws_bwc_rule_create_complex(bwc_rule,
11521154
params,
11531155
flow_source,
@@ -1216,10 +1218,9 @@ int mlx5hws_bwc_rule_action_update(struct mlx5hws_bwc_rule *bwc_rule,
12161218
return -EINVAL;
12171219
}
12181220

1219-
/* For complex rule, the update should happen on the second matcher */
1220-
if (bwc_rule->isolated_bwc_rule)
1221-
return hws_bwc_rule_action_update(bwc_rule->isolated_bwc_rule,
1222-
rule_actions);
1223-
else
1224-
return hws_bwc_rule_action_update(bwc_rule, rule_actions);
1221+
/* For complex rules, the update should happen on the last subrule. */
1222+
while (bwc_rule->next_subrule)
1223+
bwc_rule = bwc_rule->next_subrule;
1224+
1225+
return hws_bwc_rule_action_update(bwc_rule, rule_actions);
12251226
}

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@
1818

1919
#define MLX5HWS_BWC_POLLING_TIMEOUT 60
2020

21+
enum mlx5hws_bwc_matcher_type {
22+
/* Standalone bwc matcher. */
23+
MLX5HWS_BWC_MATCHER_SIMPLE,
24+
/* The first matcher of a complex matcher. When rules are inserted into
25+
* a matcher of this type, they are split into subrules and inserted
26+
* into their corresponding submatchers.
27+
*/
28+
MLX5HWS_BWC_MATCHER_COMPLEX_FIRST,
29+
/* A submatcher that is part of a complex matcher. For most purposes
30+
* these are treated as simple matchers, except when it comes to moving
31+
* rules during resize.
32+
*/
33+
MLX5HWS_BWC_MATCHER_COMPLEX_SUBMATCHER,
34+
};
35+
2136
struct mlx5hws_bwc_matcher_complex_data;
2237

2338
struct mlx5hws_bwc_matcher_size {
@@ -31,9 +46,9 @@ struct mlx5hws_bwc_matcher {
3146
struct mlx5hws_match_template *mt;
3247
struct mlx5hws_action_template **at;
3348
struct mlx5hws_bwc_matcher_complex_data *complex;
34-
struct mlx5hws_bwc_matcher *complex_first_bwc_matcher;
3549
u8 num_of_at;
3650
u8 size_of_at_array;
51+
enum mlx5hws_bwc_matcher_type matcher_type;
3752
u32 priority;
3853
struct mlx5hws_bwc_matcher_size rx_size;
3954
struct mlx5hws_bwc_matcher_size tx_size;
@@ -43,8 +58,8 @@ struct mlx5hws_bwc_matcher {
4358
struct mlx5hws_bwc_rule {
4459
struct mlx5hws_bwc_matcher *bwc_matcher;
4560
struct mlx5hws_rule *rule;
46-
struct mlx5hws_bwc_rule *isolated_bwc_rule;
47-
struct mlx5hws_bwc_complex_rule_hash_node *complex_hash_node;
61+
struct mlx5hws_bwc_rule *next_subrule;
62+
struct mlx5hws_bwc_complex_subrule_data *subrule_data;
4863
u32 flow_source;
4964
u16 bwc_queue_idx;
5065
bool skip_rx;

0 commit comments

Comments
 (0)