net/mlx5: Add flow context for flow tag
authorJianbo Liu <jianbol@mellanox.com>
Tue, 25 Jun 2019 17:47:58 +0000 (17:47 +0000)
committerSaeed Mahameed <saeedm@mellanox.com>
Wed, 26 Jun 2019 19:01:28 +0000 (12:01 -0700)
Refactor the flow data structures, add new flow_context and move
flow_tag into it, as flow_tag doesn't belong to the rule action.

Signed-off-by: Jianbo Liu <jianbol@mellanox.com>
Reviewed-by: Mark Bloch <markb@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/infiniband/hw/mlx5/flow.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/net/ethernet/mellanox/mlx5/core/diag/fs_tracepoint.h
drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
include/linux/mlx5/fs.h

index 1fc302d41a53acff4548c05df1be4552c2c3fb4d..b8841355fcd51182e93adab1829108e5804b73a6 100644 (file)
@@ -65,11 +65,12 @@ static const struct uverbs_attr_spec mlx5_ib_flow_type[] = {
 static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
        struct uverbs_attr_bundle *attrs)
 {
-       struct mlx5_flow_act flow_act = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG};
+       struct mlx5_flow_context flow_context = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG};
        struct mlx5_ib_flow_handler *flow_handler;
        struct mlx5_ib_flow_matcher *fs_matcher;
        struct ib_uobject **arr_flow_actions;
        struct ib_uflow_resources *uflow_res;
+       struct mlx5_flow_act flow_act = {};
        void *devx_obj;
        int dest_id, dest_type;
        void *cmd_in;
@@ -172,17 +173,19 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
                                   arr_flow_actions[i]->object);
        }
 
-       ret = uverbs_copy_from(&flow_act.flow_tag, attrs,
+       ret = uverbs_copy_from(&flow_context.flow_tag, attrs,
                               MLX5_IB_ATTR_CREATE_FLOW_TAG);
        if (!ret) {
-               if (flow_act.flow_tag >= BIT(24)) {
+               if (flow_context.flow_tag >= BIT(24)) {
                        ret = -EINVAL;
                        goto err_out;
                }
-               flow_act.flags |= FLOW_ACT_HAS_TAG;
+               flow_context.flags |= FLOW_CONTEXT_HAS_TAG;
        }
 
-       flow_handler = mlx5_ib_raw_fs_rule_add(dev, fs_matcher, &flow_act,
+       flow_handler = mlx5_ib_raw_fs_rule_add(dev, fs_matcher,
+                                              &flow_context,
+                                              &flow_act,
                                               counter_id,
                                               cmd_in, inlen,
                                               dest_id, dest_type);
index abac70ad5c7c46db82856e7522059611470773de..be4c9a687df754022d65d0e2f1481a3edcd22730 100644 (file)
@@ -2666,11 +2666,15 @@ int parse_flow_flow_action(struct mlx5_ib_flow_action *maction,
        }
 }
 
-static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
-                          u32 *match_v, const union ib_flow_spec *ib_spec,
+static int parse_flow_attr(struct mlx5_core_dev *mdev,
+                          struct mlx5_flow_spec *spec,
+                          const union ib_flow_spec *ib_spec,
                           const struct ib_flow_attr *flow_attr,
                           struct mlx5_flow_act *action, u32 prev_type)
 {
+       struct mlx5_flow_context *flow_context = &spec->flow_context;
+       u32 *match_c = spec->match_criteria;
+       u32 *match_v = spec->match_value;
        void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c,
                                           misc_parameters);
        void *misc_params_v = MLX5_ADDR_OF(fte_match_param, match_v,
@@ -2989,8 +2993,8 @@ static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
                if (ib_spec->flow_tag.tag_id >= BIT(24))
                        return -EINVAL;
 
-               action->flow_tag = ib_spec->flow_tag.tag_id;
-               action->flags |= FLOW_ACT_HAS_TAG;
+               flow_context->flow_tag = ib_spec->flow_tag.tag_id;
+               flow_context->flags |= FLOW_CONTEXT_HAS_TAG;
                break;
        case IB_FLOW_SPEC_ACTION_DROP:
                if (FIELDS_NOT_SUPPORTED(ib_spec->drop,
@@ -3084,7 +3088,8 @@ is_valid_esp_aes_gcm(struct mlx5_core_dev *mdev,
                return VALID_SPEC_NA;
 
        return is_crypto && is_ipsec &&
-               (!egress || (!is_drop && !(flow_act->flags & FLOW_ACT_HAS_TAG))) ?
+               (!egress || (!is_drop &&
+                            !(spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG))) ?
                VALID_SPEC_VALID : VALID_SPEC_INVALID;
 }
 
@@ -3473,7 +3478,7 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
 {
        struct mlx5_flow_table  *ft = ft_prio->flow_table;
        struct mlx5_ib_flow_handler *handler;
-       struct mlx5_flow_act flow_act = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG};
+       struct mlx5_flow_act flow_act = {};
        struct mlx5_flow_spec *spec;
        struct mlx5_flow_destination dest_arr[2] = {};
        struct mlx5_flow_destination *rule_dst = dest_arr;
@@ -3504,8 +3509,7 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
        }
 
        for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
-               err = parse_flow_attr(dev->mdev, spec->match_criteria,
-                                     spec->match_value,
+               err = parse_flow_attr(dev->mdev, spec,
                                      ib_flow, flow_attr, &flow_act,
                                      prev_type);
                if (err < 0)
@@ -3572,11 +3576,11 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
                                        MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
        }
 
-       if ((flow_act.flags & FLOW_ACT_HAS_TAG)  &&
+       if ((spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG)  &&
            (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
             flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) {
                mlx5_ib_warn(dev, "Flow tag %u and attribute type %x isn't allowed in leftovers\n",
-                            flow_act.flow_tag, flow_attr->type);
+                            spec->flow_context.flow_tag, flow_attr->type);
                err = -EINVAL;
                goto free;
        }
@@ -3947,6 +3951,7 @@ _create_raw_flow_rule(struct mlx5_ib_dev *dev,
                      struct mlx5_ib_flow_prio *ft_prio,
                      struct mlx5_flow_destination *dst,
                      struct mlx5_ib_flow_matcher  *fs_matcher,
+                     struct mlx5_flow_context *flow_context,
                      struct mlx5_flow_act *flow_act,
                      void *cmd_in, int inlen,
                      int dst_num)
@@ -3969,6 +3974,7 @@ _create_raw_flow_rule(struct mlx5_ib_dev *dev,
        memcpy(spec->match_criteria, fs_matcher->matcher_mask.match_params,
               fs_matcher->mask_len);
        spec->match_criteria_enable = fs_matcher->match_criteria_enable;
+       spec->flow_context = *flow_context;
 
        handler->rule = mlx5_add_flow_rules(ft, spec,
                                            flow_act, dst, dst_num);
@@ -4033,6 +4039,7 @@ static bool raw_fs_is_multicast(struct mlx5_ib_flow_matcher *fs_matcher,
 struct mlx5_ib_flow_handler *
 mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
                        struct mlx5_ib_flow_matcher *fs_matcher,
+                       struct mlx5_flow_context *flow_context,
                        struct mlx5_flow_act *flow_act,
                        u32 counter_id,
                        void *cmd_in, int inlen, int dest_id,
@@ -4085,7 +4092,8 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
                dst_num++;
        }
 
-       handler = _create_raw_flow_rule(dev, ft_prio, dst, fs_matcher, flow_act,
+       handler = _create_raw_flow_rule(dev, ft_prio, dst, fs_matcher,
+                                       flow_context, flow_act,
                                        cmd_in, inlen, dst_num);
 
        if (IS_ERR(handler)) {
index a043af7ee3663e79adf7ecad59ffaee694de8e30..1c205c2bd48678d853e7b41ab7e9fd71ed8e5680 100644 (file)
@@ -1317,6 +1317,7 @@ extern const struct uapi_definition mlx5_ib_devx_defs[];
 extern const struct uapi_definition mlx5_ib_flow_defs[];
 struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add(
        struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher,
+       struct mlx5_flow_context *flow_context,
        struct mlx5_flow_act *flow_act, u32 counter_id,
        void *cmd_in, int inlen, int dest_id, int dest_type);
 bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type);
index a4cf123e3f177c79fd7291b7a46f3442e58ade84..9ec46edf22a6e3fcc38e08390d51741fe186f3be 100644 (file)
@@ -204,7 +204,7 @@ TRACE_EVENT(mlx5_fs_set_fte,
                           __entry->index = fte->index;
                           __entry->action = fte->action.action;
                           __entry->mask_enable = __entry->fg->mask.match_criteria_enable;
-                          __entry->flow_tag = fte->action.flow_tag;
+                          __entry->flow_tag = fte->flow_context.flow_tag;
                           memcpy(__entry->mask_outer,
                                  MLX5_ADDR_OF(fte_match_param,
                                               &__entry->fg->mask.match_criteria,
index 4421c10f58ae5d26ed10ffd81512e6de9d339832..839662644ed382856878ffe6dee95626dd9709ee 100644 (file)
@@ -426,7 +426,7 @@ add_ethtool_flow_rule(struct mlx5e_priv *priv,
        }
 
        spec->match_criteria_enable = (!outer_header_zero(spec->match_criteria));
-       flow_act.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
+       spec->flow_context.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
        rule = mlx5_add_flow_rules(ft, spec, &flow_act, dst, dst ? 1 : 0);
        if (IS_ERR(rule)) {
                err = PTR_ERR(rule);
index 122f457091a2cb9e6207aeab953dd20c497f85d2..8ff1ca46d8d36a2f09425982eed87686b1b2b43a 100644 (file)
@@ -716,19 +716,22 @@ mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv,
                      struct mlx5e_tc_flow *flow,
                      struct netlink_ext_ack *extack)
 {
+       struct mlx5_flow_context *flow_context = &parse_attr->spec.flow_context;
        struct mlx5_nic_flow_attr *attr = flow->nic_attr;
        struct mlx5_core_dev *dev = priv->mdev;
        struct mlx5_flow_destination dest[2] = {};
        struct mlx5_flow_act flow_act = {
                .action = attr->action,
-               .flow_tag = attr->flow_tag,
                .reformat_id = 0,
-               .flags    = FLOW_ACT_HAS_TAG | FLOW_ACT_NO_APPEND,
+               .flags    = FLOW_ACT_NO_APPEND,
        };
        struct mlx5_fc *counter = NULL;
        bool table_created = false;
        int err, dest_ix = 0;
 
+       flow_context->flags |= FLOW_CONTEXT_HAS_TAG;
+       flow_context->flow_tag = attr->flow_tag;
+
        if (flow->flags & MLX5E_TC_FLOW_HAIRPIN) {
                err = mlx5e_hairpin_flow_add(priv, flow, parse_attr, extack);
                if (err) {
index 52c47d3dd5a5432efbe1b1816a86c71cc8cb09cc..c76da309506b257307ba1de0582176bc60780d83 100644 (file)
@@ -636,7 +636,8 @@ static bool mlx5_is_fpga_egress_ipsec_rule(struct mlx5_core_dev *dev,
                                           u8 match_criteria_enable,
                                           const u32 *match_c,
                                           const u32 *match_v,
-                                          struct mlx5_flow_act *flow_act)
+                                          struct mlx5_flow_act *flow_act,
+                                          struct mlx5_flow_context *flow_context)
 {
        const void *outer_c = MLX5_ADDR_OF(fte_match_param, match_c,
                                           outer_headers);
@@ -655,7 +656,7 @@ static bool mlx5_is_fpga_egress_ipsec_rule(struct mlx5_core_dev *dev,
            (match_criteria_enable &
             ~(MLX5_MATCH_OUTER_HEADERS | MLX5_MATCH_MISC_PARAMETERS)) ||
            (flow_act->action & ~(MLX5_FLOW_CONTEXT_ACTION_ENCRYPT | MLX5_FLOW_CONTEXT_ACTION_ALLOW)) ||
-            (flow_act->flags & FLOW_ACT_HAS_TAG))
+            (flow_context->flags & FLOW_CONTEXT_HAS_TAG))
                return false;
 
        return true;
@@ -767,7 +768,8 @@ mlx5_fpga_ipsec_fs_create_sa_ctx(struct mlx5_core_dev *mdev,
                                            fg->mask.match_criteria_enable,
                                            fg->mask.match_criteria,
                                            fte->val,
-                                           &fte->action))
+                                           &fte->action,
+                                           &fte->flow_context))
                return ERR_PTR(-EINVAL);
        else if (!mlx5_is_fpga_ipsec_rule(mdev,
                                          fg->mask.match_criteria_enable,
index 4f1d402926f193b290653aebd09f24997353bc72..fb1335a433ae5d75f8f3d2710216a391bf191a35 100644 (file)
@@ -396,7 +396,8 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
        in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
        MLX5_SET(flow_context, in_flow_context, group_id, group_id);
 
-       MLX5_SET(flow_context, in_flow_context, flow_tag, fte->action.flow_tag);
+       MLX5_SET(flow_context, in_flow_context, flow_tag,
+                fte->flow_context.flow_tag);
        MLX5_SET(flow_context, in_flow_context, extended_destination,
                 extended_dest);
        if (extended_dest) {
index fb5b61727ee70845cf9a980c5805eaf19f174640..9f5544ac6b8a581b3c1fd101ee45c458bd70e307 100644 (file)
@@ -584,7 +584,7 @@ err_ida_remove:
 }
 
 static struct fs_fte *alloc_fte(struct mlx5_flow_table *ft,
-                               u32 *match_value,
+                               struct mlx5_flow_spec *spec,
                                struct mlx5_flow_act *flow_act)
 {
        struct mlx5_flow_steering *steering = get_steering(&ft->node);
@@ -594,9 +594,10 @@ static struct fs_fte *alloc_fte(struct mlx5_flow_table *ft,
        if (!fte)
                return ERR_PTR(-ENOMEM);
 
-       memcpy(fte->val, match_value, sizeof(fte->val));
+       memcpy(fte->val, &spec->match_value, sizeof(fte->val));
        fte->node.type =  FS_TYPE_FLOW_ENTRY;
        fte->action = *flow_act;
+       fte->flow_context = spec->flow_context;
 
        tree_init_node(&fte->node, NULL, del_sw_fte);
 
@@ -1428,7 +1429,9 @@ static bool check_conflicting_actions(u32 action1, u32 action2)
        return false;
 }
 
-static int check_conflicting_ftes(struct fs_fte *fte, const struct mlx5_flow_act *flow_act)
+static int check_conflicting_ftes(struct fs_fte *fte,
+                                 const struct mlx5_flow_context *flow_context,
+                                 const struct mlx5_flow_act *flow_act)
 {
        if (check_conflicting_actions(flow_act->action, fte->action.action)) {
                mlx5_core_warn(get_dev(&fte->node),
@@ -1436,12 +1439,12 @@ static int check_conflicting_ftes(struct fs_fte *fte, const struct mlx5_flow_act
                return -EEXIST;
        }
 
-       if ((flow_act->flags & FLOW_ACT_HAS_TAG) &&
-           fte->action.flow_tag != flow_act->flow_tag) {
+       if ((flow_context->flags & FLOW_CONTEXT_HAS_TAG) &&
+           fte->flow_context.flow_tag != flow_context->flow_tag) {
                mlx5_core_warn(get_dev(&fte->node),
                               "FTE flow tag %u already exists with different flow tag %u\n",
-                              fte->action.flow_tag,
-                              flow_act->flow_tag);
+                              fte->flow_context.flow_tag,
+                              flow_context->flow_tag);
                return -EEXIST;
        }
 
@@ -1449,7 +1452,7 @@ static int check_conflicting_ftes(struct fs_fte *fte, const struct mlx5_flow_act
 }
 
 static struct mlx5_flow_handle *add_rule_fg(struct mlx5_flow_group *fg,
-                                           u32 *match_value,
+                                           struct mlx5_flow_spec *spec,
                                            struct mlx5_flow_act *flow_act,
                                            struct mlx5_flow_destination *dest,
                                            int dest_num,
@@ -1460,7 +1463,7 @@ static struct mlx5_flow_handle *add_rule_fg(struct mlx5_flow_group *fg,
        int i;
        int ret;
 
-       ret = check_conflicting_ftes(fte, flow_act);
+       ret = check_conflicting_ftes(fte, &spec->flow_context, flow_act);
        if (ret)
                return ERR_PTR(ret);
 
@@ -1635,7 +1638,7 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
        u64  version;
        int err;
 
-       fte = alloc_fte(ft, spec->match_value, flow_act);
+       fte = alloc_fte(ft, spec, flow_act);
        if (IS_ERR(fte))
                return  ERR_PTR(-ENOMEM);
 
@@ -1651,8 +1654,7 @@ search_again_locked:
                fte_tmp = lookup_fte_locked(g, spec->match_value, take_write);
                if (!fte_tmp)
                        continue;
-               rule = add_rule_fg(g, spec->match_value,
-                                  flow_act, dest, dest_num, fte_tmp);
+               rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte_tmp);
                up_write_ref_node(&fte_tmp->node, false);
                tree_put_node(&fte_tmp->node, false);
                kmem_cache_free(steering->ftes_cache, fte);
@@ -1699,8 +1701,7 @@ skip_search:
 
                nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD);
                up_write_ref_node(&g->node, false);
-               rule = add_rule_fg(g, spec->match_value,
-                                  flow_act, dest, dest_num, fte);
+               rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte);
                up_write_ref_node(&fte->node, false);
                tree_put_node(&fte->node, false);
                return rule;
@@ -1786,7 +1787,7 @@ search_again_locked:
        if (err)
                goto err_release_fg;
 
-       fte = alloc_fte(ft, spec->match_value, flow_act);
+       fte = alloc_fte(ft, spec, flow_act);
        if (IS_ERR(fte)) {
                err = PTR_ERR(fte);
                goto err_release_fg;
@@ -1800,8 +1801,7 @@ search_again_locked:
 
        nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD);
        up_write_ref_node(&g->node, false);
-       rule = add_rule_fg(g, spec->match_value, flow_act, dest,
-                          dest_num, fte);
+       rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte);
        up_write_ref_node(&fte->node, false);
        tree_put_node(&fte->node, false);
        tree_put_node(&g->node, false);
index a08c3d09a50f0cc80423ed594a601f52e55a0381..c48c382f926f33b5747c5f5603c18713a03e6bd0 100644 (file)
@@ -170,6 +170,7 @@ struct fs_fte {
        u32                             val[MLX5_ST_SZ_DW_MATCH_PARAM];
        u32                             dests_size;
        u32                             index;
+       struct mlx5_flow_context        flow_context;
        struct mlx5_flow_act            action;
        enum fs_fte_status              status;
        struct mlx5_fc                  *counter;
index 2ddaa97f217988c0101da96f1973eac27f104fb4..9bf49ce218fa8c89aa5627fa210ceff3a6ec1ae2 100644 (file)
@@ -88,10 +88,20 @@ struct mlx5_flow_group;
 struct mlx5_flow_namespace;
 struct mlx5_flow_handle;
 
+enum {
+       FLOW_CONTEXT_HAS_TAG = BIT(0),
+};
+
+struct mlx5_flow_context {
+       u32 flags;
+       u32 flow_tag;
+};
+
 struct mlx5_flow_spec {
        u8   match_criteria_enable;
        u32  match_criteria[MLX5_ST_SZ_DW(fte_match_param)];
        u32  match_value[MLX5_ST_SZ_DW(fte_match_param)];
+       struct mlx5_flow_context flow_context;
 };
 
 enum {
@@ -173,13 +183,11 @@ struct mlx5_fs_vlan {
 #define MLX5_FS_VLAN_DEPTH     2
 
 enum {
-       FLOW_ACT_HAS_TAG   = BIT(0),
-       FLOW_ACT_NO_APPEND = BIT(1),
+       FLOW_ACT_NO_APPEND = BIT(0),
 };
 
 struct mlx5_flow_act {
        u32 action;
-       u32 flow_tag;
        u32 reformat_id;
        u32 modify_id;
        uintptr_t esp_id;
@@ -190,7 +198,6 @@ struct mlx5_flow_act {
 
 #define MLX5_DECLARE_FLOW_ACT(name) \
        struct mlx5_flow_act name = { .action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,\
-                                     .flow_tag = MLX5_FS_DEFAULT_FLOW_TAG, \
                                      .reformat_id = 0, \
                                      .modify_id = 0, \
                                      .flags =  0, }