diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c index 4187f2b112b8..32e94d2ee5e4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c @@ -595,6 +595,18 @@ static void dr_rule_clean_rule_members(struct mlx5dr_rule *rule, } } +static u16 dr_get_bits_per_mask(u16 byte_mask) +{ + u16 bits = 0; + + while (byte_mask) { + byte_mask = byte_mask & (byte_mask - 1); + bits++; + } + + return bits; +} + static bool dr_rule_need_enlarge_hash(struct mlx5dr_ste_htbl *htbl, struct mlx5dr_domain *dmn, struct mlx5dr_domain_rx_tx *nic_dmn) @@ -607,6 +619,9 @@ static bool dr_rule_need_enlarge_hash(struct mlx5dr_ste_htbl *htbl, if (!ctrl->may_grow) return false; + if (dr_get_bits_per_mask(htbl->byte_mask) * BITS_PER_BYTE <= htbl->chunk_size) + return false; + if (ctrl->num_of_collisions >= ctrl->increase_threshold && (ctrl->num_of_valid_entries - ctrl->num_of_collisions) >= ctrl->increase_threshold) return true; @@ -788,12 +803,10 @@ again: * it means that all the previous stes are the same, * if so, this rule is duplicated. */ - if (mlx5dr_ste_is_last_in_rule(nic_matcher, - matched_ste->ste_chain_location)) { - mlx5dr_info(dmn, "Duplicate rule inserted, aborting!!\n"); - return NULL; - } - return matched_ste; + if (!mlx5dr_ste_is_last_in_rule(nic_matcher, ste_location)) + return matched_ste; + + mlx5dr_dbg(dmn, "Duplicate rule inserted\n"); } if (!skip_rehash && dr_rule_need_enlarge_hash(cur_htbl, dmn, nic_dmn)) { @@ -956,12 +969,12 @@ static int dr_rule_destroy_rule(struct mlx5dr_rule *rule) return 0; } -static bool dr_rule_is_ipv6(struct mlx5dr_match_param *param) +static enum mlx5dr_ipv dr_rule_get_ipv(struct mlx5dr_match_spec *spec) { - return (param->outer.ip_version == 6 || - param->inner.ip_version == 6 || - param->outer.ethertype == ETH_P_IPV6 || - param->inner.ethertype == ETH_P_IPV6); + if (spec->ip_version == 6 || spec->ethertype == ETH_P_IPV6) + return DR_RULE_IPV6; + + return DR_RULE_IPV4; } static bool dr_rule_skip(enum mlx5dr_domain_type domain, @@ -1025,7 +1038,8 @@ dr_rule_create_rule_nic(struct mlx5dr_rule *rule, ret = mlx5dr_matcher_select_builders(matcher, nic_matcher, - dr_rule_is_ipv6(param)); + dr_rule_get_ipv(¶m->outer), + dr_rule_get_ipv(¶m->inner)); if (ret) goto out_err; @@ -1098,6 +1112,8 @@ dr_rule_create_rule_nic(struct mlx5dr_rule *rule, if (htbl) mlx5dr_htbl_put(htbl); + kfree(hw_ste_arr); + return 0; free_ste: |