net/mlx5: DR, Add support for rule creation with flow source hint
authorHamdan Igbaria <hamdani@nvidia.com>
Mon, 15 Jun 2020 15:18:14 +0000 (18:18 +0300)
committerSaeed Mahameed <saeedm@nvidia.com>
Thu, 1 Oct 2020 04:26:28 +0000 (21:26 -0700)
Skip the rule according to flow arrival source, in case of RX and the
source is local port skip and in case of TX and the source is uplink
skip, we get this info according to the flow source hint we get from
upper layers when creating the rule.
This is needed because for example in case of FDB table which has a TX
and RX tables and we are inserting a rule with an encap action which
is only a TX action, in this case rule will fail on RX, so we can rely
on the flow source hint and skip RX in such case.
Until now we relied on metadata regc_0 that upper layer mapped the
port in the regc_0, but the problem is that upper layer did not always
use regc_0 for port mapping, so now we added support to flow source
hint which upper layers will pass to SW steering when creating a rule.

Signed-off-by: Alex Vesker <valex@nvidia.com>
Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h
drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c
drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h

index 1757718..b3c9dc0 100644 (file)
@@ -985,31 +985,28 @@ static enum mlx5dr_ipv dr_rule_get_ipv(struct mlx5dr_match_spec *spec)
 static bool dr_rule_skip(enum mlx5dr_domain_type domain,
                         enum mlx5dr_ste_entry_type ste_type,
                         struct mlx5dr_match_param *mask,
-                        struct mlx5dr_match_param *value)
+                        struct mlx5dr_match_param *value,
+                        u32 flow_source)
 {
+       bool rx = ste_type == MLX5DR_STE_TYPE_RX;
+
        if (domain != MLX5DR_DOMAIN_TYPE_FDB)
                return false;
 
        if (mask->misc.source_port) {
-               if (ste_type == MLX5DR_STE_TYPE_RX)
-                       if (value->misc.source_port != WIRE_PORT)
-                               return true;
+               if (rx && value->misc.source_port != WIRE_PORT)
+                       return true;
 
-               if (ste_type == MLX5DR_STE_TYPE_TX)
-                       if (value->misc.source_port == WIRE_PORT)
-                               return true;
+               if (!rx && value->misc.source_port == WIRE_PORT)
+                       return true;
        }
 
-       /* Metadata C can be used to describe the source vport */
-       if (mask->misc2.metadata_reg_c_0) {
-               if (ste_type == MLX5DR_STE_TYPE_RX)
-                       if ((value->misc2.metadata_reg_c_0 & WIRE_PORT) != WIRE_PORT)
-                               return true;
+       if (rx && flow_source == MLX5_FLOW_CONTEXT_FLOW_SOURCE_LOCAL_VPORT)
+               return true;
+
+       if (!rx && flow_source == MLX5_FLOW_CONTEXT_FLOW_SOURCE_UPLINK)
+               return true;
 
-               if (ste_type == MLX5DR_STE_TYPE_TX)
-                       if ((value->misc2.metadata_reg_c_0 & WIRE_PORT) == WIRE_PORT)
-                               return true;
-       }
        return false;
 }
 
@@ -1038,7 +1035,8 @@ dr_rule_create_rule_nic(struct mlx5dr_rule *rule,
 
        INIT_LIST_HEAD(&nic_rule->rule_members_list);
 
-       if (dr_rule_skip(dmn->type, nic_dmn->ste_type, &matcher->mask, param))
+       if (dr_rule_skip(dmn->type, nic_dmn->ste_type, &matcher->mask, param,
+                        rule->flow_source))
                return 0;
 
        hw_ste_arr = kzalloc(DR_RULE_MAX_STE_CHAIN * DR_STE_SIZE, GFP_KERNEL);
@@ -1173,7 +1171,8 @@ static struct mlx5dr_rule *
 dr_rule_create_rule(struct mlx5dr_matcher *matcher,
                    struct mlx5dr_match_parameters *value,
                    size_t num_actions,
-                   struct mlx5dr_action *actions[])
+                   struct mlx5dr_action *actions[],
+                   u32 flow_source)
 {
        struct mlx5dr_domain *dmn = matcher->tbl->dmn;
        struct mlx5dr_match_param param = {};
@@ -1188,6 +1187,7 @@ dr_rule_create_rule(struct mlx5dr_matcher *matcher,
                return NULL;
 
        rule->matcher = matcher;
+       rule->flow_source = flow_source;
        INIT_LIST_HEAD(&rule->rule_actions_list);
 
        ret = dr_rule_add_action_members(rule, num_actions, actions);
@@ -1232,13 +1232,14 @@ free_rule:
 struct mlx5dr_rule *mlx5dr_rule_create(struct mlx5dr_matcher *matcher,
                                       struct mlx5dr_match_parameters *value,
                                       size_t num_actions,
-                                      struct mlx5dr_action *actions[])
+                                      struct mlx5dr_action *actions[],
+                                      u32 flow_source)
 {
        struct mlx5dr_rule *rule;
 
        refcount_inc(&matcher->refcount);
 
-       rule = dr_rule_create_rule(matcher, value, num_actions, actions);
+       rule = dr_rule_create_rule(matcher, value, num_actions, actions, flow_source);
        if (!rule)
                refcount_dec(&matcher->refcount);
 
index 46e7a00..f50f3b1 100644 (file)
@@ -797,6 +797,7 @@ struct mlx5dr_rule {
        struct mlx5dr_rule_rx_tx rx;
        struct mlx5dr_rule_rx_tx tx;
        struct list_head rule_actions_list;
+       u32 flow_source;
 };
 
 void mlx5dr_rule_update_rule_member(struct mlx5dr_ste *new_ste,
index 9b08eb5..96c39a1 100644 (file)
@@ -487,7 +487,8 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
        rule = mlx5dr_rule_create(group->fs_dr_matcher.dr_matcher,
                                  &params,
                                  num_actions,
-                                 actions);
+                                 actions,
+                                 fte->flow_context.flow_source);
        if (!rule) {
                err = -EINVAL;
                goto free_actions;
index 7deaca9..7914fe3 100644 (file)
@@ -67,7 +67,8 @@ struct mlx5dr_rule *
 mlx5dr_rule_create(struct mlx5dr_matcher *matcher,
                   struct mlx5dr_match_parameters *value,
                   size_t num_actions,
-                  struct mlx5dr_action *actions[]);
+                  struct mlx5dr_action *actions[],
+                  u32 flow_source);
 
 int mlx5dr_rule_destroy(struct mlx5dr_rule *rule);